写vue项目用的axios库,在处理下载文件的时候,发现后端返回的是文件流,无法直接下载,只能用a标签处理,但是对于有鉴权的下载,a标签显然是不合适的了。于是乎就查阅各种资料各种鼓捣终于搞出来了
axios请求下载
请求下载的时候设置responseType为blob,例如:
export function apiDownloadFiles(fielId) {
return axios({
url: `/document/${fielId}`,
method: 'get',
responseType: 'blob'
})
}
这样请求就会走axios拦截器里配置的方法,你就可以给下载添加请求头token了
请求后获取到的文件流如何下载到本地呢?
后端返回了的文件流是这样的
这个时候要怎么处理才能变成文件呢?apiDownloadFiles(file.id).then(res => {
if (res.data.type === "application/json") {
this.$message({
type: "error",
message: "下载失败,文件不存在或权限不足"
});
} else {
let blob = new Blob([res.data]);
if (window.navigator.msSaveOrOpenBlob) {
navigator.msSaveBlob(blob, file.fileName);
} else {
let link = document.createElement("a");
let evt = document.createEvent("HTMLEvents");
evt.initEvent("click", false, false);
link.href = URL.createObjectURL(blob);
link.download = file.fileName;
link.style.display = "none";
document.body.appendChild(link);
link.click();
window.URL.revokeObjectURL(link.href);
}
}
});
模拟a标签点击,成功下载文件。 如果没有太多参数的下载文件,可以直接下载,这种没有token,比较适合用cookies和后端做认证的。
const link = document.createElement('a')
const evt = document.createEvent('HTMLEvents')
evt.initEvent('click', false, false)
link.href = `${process.env.BASE_API}/template/download/${this.fileId}`
link.target = '_blank'
link.style.display = 'none'
document.body.appendChild(link)
link.click()
window.URL.revokeObjectURL(link.href)