一、两种方式:
1、后台提供一个 URL,然后用 window.open(URL) 下载
2、后台直接返回文件的二进制内容,然后前端转化一下再下载
二、Blob对象:
1、Blob,全称:Binary Large Object,表示不可变的类似文件对象的二进制数据。
2、构造函数:Blob(blobParts[, options])
参数说明:
常用写法:var blob = new Blob([res], { type: res.type });
解释:res 为请求响应结果,使用 type 指定MIME类型(否则为"")
3、使用场景:
三、根据前端返回的二进制文件流下载文件:
示例代码:当文件状态改变时触发上传批量导入文件,批量导入完成后会返回一个反馈文件的二进制流,我们需要将该二进制流下载为文件。
fileChange(file) {
const formData = new FormData();
this.$confirm('是否上传此文件?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
formData.append('file', file.raw)
iccard.batchImport(formData).then((res) => {
const blob = new Blob([res], { type: res.type });
let dom = document.createElement("a");
let url = window.URL.createObjectURL(blob);
dom.href = url;
dom.download = decodeURI('批量导入结果反馈.xlsx');
dom.style.display = "none";
document.body.appendChild(dom);
dom.click();
dom.parentNode.removeChild(dom);
window.URL.revokeObjectURL(url);
});
this.$message({
type: 'success',
message: '上传成功!'
});
}).catch(() => {
this.$message({
type: 'info',
message: '取消上传'
});
});
},
总结:大体思路就是获取到文件url,然后通过创建document节点--超链接,为节点绑定一个点击事件。
四、之后加的需求:
因为之前没有考虑到excel格式、服务器异常等情况,所以当出现500错误时还是会在导入完成后下载文件,但是下载出的文件报了500且存在乱码,此时我们的需求就是出现500时不下载文件,只在前端提示用户。
解决:
因为相应的api接口中要求数据返回类型为 ”blob“,所以非文件处理的请求拦截器不适用,那么我们就新创建一个拦截器文件,专门处理文件下载请求。
其次,在方法中通过对 type 的判断来决定是否要下载导入后的反馈文件还是进行错误提示。
其中,加深了我对响应字段 content-type 的理解,后端一般返回的数据类型都是 application/json ,excel文件的话就是 application/vnd.ms-excel ,所以我们可以根据这点来进行相应的判断。
最后,对 api 接口中的 responseType: "blob" 还是有点不理解,它到底起了什么作用?
代码:
iccard.batchImport(formData).then((res) => {
if (res.data.type == "application/json") {
var innerData;
var reader = new FileReader();
reader.readAsText(res.data, "utf-8");
reader.onload = () => {
innerData = JSON.parse(reader.result);
if (innerData.code == 500) {
this.$notify({
type: "error",
message: innerData.msg,
});
return;
}
};
}else if (res.data.type == "application/vnd.ms-excel") {
fileUtil
.downloadFile(res, "批量导入结果反馈")
.then(() => {
this.$notify({
type: "success",
message: "下载成功",
});
})
.catch(() => {
this.$notify({
type: "error",
message: "下载失败",
});
});
} else {
this.$notify({
type: "error",
message: "文件格式不正确",
});
}
});