背景
有一个接口,是上传excel,后端进行批量处理
如果有数据失败,返回一个失败的excel文件流
如果都成功,返回一个json
问题分析
如果是下载文件的接口,前端请求的时候对于responseType
只能设置为其中一种格式
那么默认情况下,另外一种情况的返回就无法正常读取到
关键点
- 在axios的
result.data.type
中可以获取到真实的返回类型,即使请求的content-type
是blob
- 如果实际是
json
的话,可以通过result.data.text().then((text) => {})
获取到json数据// 通过这种方式取出返回的errorMsg blob.text().then((text) => { ElMessage.error(JSON.parse(text).debugMsg); });
完整实现
const download = async (url: string, data: any): Promise<any> => {
const loadingInstance = ElLoading.service();
const result = await axios.post(
BASE_URL + url,
deleteObjectFalsityValueAttribute(data),
{
withCredentials: true,
responseType: "blob",
timeout: 4 * 60 * 1000,
}
);
// 如果返回不是文件类型,需要提示
if (result.data.type === "application/json") {
const blob = result.data;
// 通过这种方式取出返回的errorMsg
blob.text().then((text) => {
ElMessage.error(JSON.parse(text).debugMsg);
});
loadingInstance.close();
return false;
}
const blobData: any[] = [];
blobData.push(result.data);
const download_url = window.URL.createObjectURL(
new Blob(blobData, {
type: result.data.type })
);
const a = document.createElement("a");
a.href = download_url;
let fileName = result.headers["content-disposition"].substr(20);
// 如果是zip类型需要解码后端base64加密的
if (result.data.type === "application/octet-stream") {
fileName = decodeBase64(fileName);
}
a.download = decodeURI(fileName).replace("=utf-8''", "");
document.body.appendChild(a);
a.click();
a.remove();
loadingInstance.close();
return true;
};