针对流文件api响应拦截处理

76 阅读1分钟

废话不多说直接上代码


/** *
 * 基础配置
 */
const options: AxiosRequestConfig = {
  baseURL: import.meta.env.VITE_APP_PROXY_URL,
  timeout: 100000,
  withCredentials: true,
};
const axiosInstance = axios.create(options);
/** *
 * 响应拦截
 */
axiosInstance.interceptors.response.use(
  resp => {
    // 二进制数据处理
    if (resp.request.responseType === 'blob' || resp.request.responseType === 'arraybuffer') {
      if (resp.data.type === 'application/json') {
        const reader = new FileReader();
        reader.onload = () => {
          // TODO 错误处理
          if (reader.result) {
            const res = JSON.parse(reader.result as string);
            if (![0, 200].includes(res.code)) {
              //... 可增加错误提示
              throw Error(resp.data);
            }
          }
        };
        reader.readAsText(resp.data);
        throw Error(resp.data);
      } else {
        // 处理展示非下载流数据(例如:图片验证码)
        if (resp.headers['content-type'] === 'image/gif') {
          return resp.data;
        }
        let fileName = 'file.xlsx'
        const contentDisposition = resp.headers['content-disposition'];
        if (contentDisposition.indexOf('filename') !== -1) {
          const encoded = contentDisposition.split(';')[1].split('=')[1]
          fileName = decodeURIComponent(encoded); // decodeURI(escape(encoded))
        } 
        downloadFile(resp.data, fileName)
      }
    } else {
      // eslint-disable-next-line @typescript-eslint/ban-ts-comment
      // @ts-ignore
      if (resp.config.notDealWithData) {
        return resp;
      }
      if (![0, 200].includes(resp.data.code) || (!resp.data.success && resp.status !== 200)) {
         //... 可增加错误提示
        throw Error(resp.data);
      }
      return resp.data;
    }
  },
  error => {
    if (error?.config?.notDealWithError) {
      return Promise.reject(error);
    }
    //... 可增加错误提示
    return Promise.reject(error);
  }
);

const downloadFile = (file: Blob, fileName = 'file.xlsx') => {
  if (file) {
    const blob = new Blob([file]);
    // 获取heads中的filename文件名
    const downloadElement = document.createElement('a');
    // 创建下载的链接
    const href = window.URL.createObjectURL(blob);
    downloadElement.href = href;
    // 下载后文件名
    downloadElement.download = fileName;
    document.body.appendChild(downloadElement);
    // 点击下载
    downloadElement.click();
    // 下载完成移除元素
    document.body.removeChild(downloadElement);
    // 释放掉blob对象
    window.URL.revokeObjectURL(href);
  }
};