背景:
下载文件失败时,要提示后端返回的错误信息,而不是将错误信息流写到下载的文件中。
知识点:
- 下载文件请求,需要设置responseType为blob或arraybuffer
const xhr = new XMLHttpRequest()
xhr.responseType = 'arraybuffer'
// xhr.responseType = 'blob'
错误信息
- responseType为arraybuffer
this.$api.xxx().then((res) => {
console.log(res); // arrayBuffer数据
var reader = new FileReader();
reader.onload = (data) => {
// 是错误信息返回
if (data.target && data.target.result) {
let result = data.target.result;
if (
typeof result === "string" &&
result.includes("code") &&
result.includes("msg")
) {
result = JSON.parse(data.target.result);
this.$message.error(result.msg);
return;
}
}
// 是文件
// 此处省略下载文件代码。。。
}
}
reader.readAsText(new Blob([res], { type: "application/json" })); // 按照json解析
}.catch((err) => {
console.log('导出失败')
});
- responseType为blob
this.$api.xxx().then((res) => {
console.log(res); // Blob对象 { size: 1234, type: "xxxxxx"}
// Blob对象根据mdn描述,如果能解析,type是有值的,不然为空字符串
// 这里返回是表格文件和JSON数据
// 因此type会为:
// 文件:application/octet-stream
// JSON数据:application/json
// 进行简单判断为blob对象:
if(res && res.type) {
let type = res.type;
if(type === "application/octet-stream") {
// Blob 对象处理
// 此处省略下载文件代码。。。
return;
}
if(type === "application/json") {
// json 数据处理
let reader = new FileReader();
reader.onload = (data) => {
// data是个对象 {..., target: { ..., result: 'asda', ....}}
// 会有一个target属性里包含了返回的JSON
if (data.target && data.target.result) {
let result = data.target.result;
// 进行自定义校验
if (
typeof result === "string" &&
result.includes("code") &&
result.includes("msg")
) {
result = JSON.parse(data.target.result);
// 自定义处理
return;
}
}
};
reader.error= (err)=> {
// 读取失败,自定义处理
console.log(err)
}
// 数据解析为json,理解为读取文件数据
reader.readAsText(new Blob([res], { type: "application/json" }));
return;
}
}
// 没有这里直接就算失败吧,根据实际情况自定义
console.log('导出失败')
}.catch((err) => {
console.log('导出失败')
});