最近发现了一个挺奇怪的问题,前端导出功能,因为数据量太大,后端返回的是报错信息,但是拦截器却接收不到

浏览器中的预览信息,后端明明返回的是500,如下:

然后我去拦截器中打印:

后续我得出了结论:问题在于当后端返回错误时,由于设置了 responseType: "blob",错误信息被封装在 Blob 中无法直接读取

以下是我的导出方法:

export const downLoadFile = (url, method, data, fileName) => {
  return request({
    method,
    url: process.env.BASE_API + url,
    data,
    responseType: "blob",
    headers: {
      Authorization: getToken()
    }
  })
    .then(async res => {
      // 检查 Blob 类型是否为 JSON(表示错误)
      if (res.data.type === "application/json") {
        const errorData = await parseBlobToJson(res.data);
        console.log('errorData', errorData);

        const errorMsg = errorData.message || "导出失败";
        Message.error(errorMsg);
        return Promise.reject(new Error(errorMsg));
      }


      // 老版本
      const blob = new Blob([res.data]);
      const url = window.URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.style.display = "none";
      a.href = url;
      a.download = fileName;
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
      window.URL.revokeObjectURL(url); // 增加内存释放
      console.log('url', url);
      Message({
        message: "导出成功",
        type: "success"
      });
    })
    .catch(error => {
      // 错误信息已在前面的 JSON 处理中显示,此处捕获网络错误
      const errMsg = error.message || "导出失败";
      Message.error(errMsg);
      return Promise.reject(error);
    })
}

我通过 if (res.data.type === "application/json")  来拦截错误信息,至于为什么是这个来判断,以下是我个人理解(不知道对不对):

正常导出:后端返回的是二进制流(如Excel),其Content-Type通常是:

  • application/vnd.ms-excel

  • application/octet-stream

  • application/zip 等

错误情况:后端返回的是 JSON 错误信息,其 Content-Type 是 application/json 

以下是解析blob为 json的辅助函数,搭配上面的导出使用

// 解析 Blob 为 JSON 的辅助函数
export const parseBlobToJson = (blob) => {
  return new Promise((resolve) => {
    const reader = new FileReader();
    reader.onload = () => {
      try {
        resolve(JSON.parse(reader.result));
      } catch (err) {
        resolve({ message: "未知错误格式" });
      }
    };
    reader.readAsText(blob);
  });
}

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐