背景
下载文件接口,在支持正常文件流下载的同时,需支持失败错误提示。
- 正常情况下:返回blob格式数据。
- 异常情况下:返回json数据,提示用户失败原因。
问题
接口的responseType只能设置一种格式,responseType="blob"或者responseType="application/json"。这里支持文件下载,需设置为blob,这时返回json时,获取responseText会报错。
responseText: [Exception: DOMException: Failed to read the 'responseText' property from 'XMLHttpRequest'
解法
responseType设置为blob
- 返回blob数据时,进行接收下载。
const link = document.createElement('a');
link.style.display = 'none';
// a 标签的 download 属性就是下载下来的文件名
link.download = fileName;
link.href = URL.createObjectURL(blob);
document.body.appendChild(link);
link.click();
// 释放的 URL 对象以及移除 a 标签
URL.revokeObjectURL(link.href);
document.body.removeChild(link);
- 返回json数据时,将blob格式转换为json
const reader = new FileReader();
reader.readAsText(blob, 'utf-8');
reader.onload = function(e) {
const readerRes = reader.result;
const parseObj = JSON.parse(readerRes);
const { code, msg } = parseObj;
// 处理逻辑...
};
总结
const downloadBlob = (url, fileName = '', extraOptions) => {
const options = {
credentials: 'include',
...extraOptions
};
fetch(url, options).then(res => {
res.blob().then(blob => {
if (blob.type == 'application/json') {
const reader = new FileReader();
reader.readAsText(blob, 'utf-8');
reader.onload = function(e) {
const readerres = reader.result;
const parseObj = JSON.parse(readerres);
const { code, msg } = parseObj;
if (code === 'xxx') {
Modal.error({
title: '提示',
content: msg
});
} else {
message.error('导出失败');
}
};
return;
}
if (window.navigator.msSaveOrOpenBlob) {
navigator.msSaveBlob(blob, fileName);
} else {
const link = document.createElement('a');
link.style.display = 'none';
// a 标签的 download 属性就是下载下来的文件名
link.download = fileName;
link.href = URL.createObjectURL(blob);
document.body.appendChild(link);
link.click();
// 释放的 URL 对象以及移除 a 标签
URL.revokeObjectURL(link.href);
document.body.removeChild(link);
}
});
});
};