前端导出 responseType: “blob“ 无法正确获取到后端返回值
·
最近发现了一个挺奇怪的问题,前端导出功能,因为数据量太大,后端返回的是报错信息,但是拦截器却接收不到
浏览器中的预览信息,后端明明返回的是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);
});
}
更多推荐


所有评论(0)