前端下载文件流的方法很简单,axios 的请求方式请求头增加 responseType 为 blob 响应体转成 Blob 对象
axios({
method: 'get',
url: XXX,
responseType: 'blob', // 将响应类型设置为'blob'
data: param,
})
我最近需求是后端成功会返回文件流。其他情况会返回状态码
然后我就兴奋的去开发了,然后问题就出来了,因为指定 responseType 所以拿到的后端数据通过 axios 之后全部变成了 Blob 对象,然后我就找不到了我的状态码了 T_T
解决办法很奇葩,用到了 FileReader 对象解决,只要解析 Blob 数据能成功,就取出 code 码提示,一旦报错,就是文件流了,哈哈哈哈哈哈
完整代码如下
getPDFPreview(row, column, cellValue, index) {
row.loading = true;
const { vin, orderNum } = row;
get({ vin, orderNum })
.then((data) => {
/**
* response.addHeader("content-Disposition", "attachment,filename=" + URlEncoder.encode(filename, "UTF-8"));
* 后端请求头 Content-Disposition 的 attachment 改为 inline 就可以支持预览
*/
const blob = new Blob([data], { type: "application/pdf" });
/**
* 使用 FileReader 对象解析
* 解析出错就是文件流 application/pdf
* 解析出 JSON 格式就是后端返回的文件状态,提示用户
*/
const reader = new FileReader();
reader.onload = (event) => {
new Promise((resolve, reject) => {
const contents = event.target.result;
const response = JSON.parse(contents);
resolve(response);
})
.then((res) => {
row.loading = false;
this.$message({
type: "error",
message: res.msg,
customClass: this.errorCustomClass,
showClose: true,
duration: 0,
});
})
.catch((_) => {
row.loading = false;
const url = window.URL.createObjectURL(blob);
window.open(url);
});
};
// 以文本形式读取 Blob 内容
reader.readAsText(blob);
})
.catch((err) => {
// console.log(err);
});
},
这里也有提到一个小技巧,下载 PDF 的时候,后端如果设置响应头 Content-Disposition 为 inline 就可以直接预览
今天就这样!