项目场景:
需求要求点击下载附件后,下载后端返回来的多个文件url数组
问题描述
使用a标签download只能实现点击一个下载一个文件,并且pdf和图片文件会自动打开,不符合需要的效果,于是改用手动创建a标签的方法进行遍历下载,发现部署到服务器后存在跨域下载问题(前后端分离)。
原因分析:
查了文档才发现这个方法只适用于同源文件,解决方法有两种:一是让后端返回二进制文件流进行下载,二是前端自行转换为文件流,因为我这边是文件url字段是和其他字段一起返回的,所以采用了第二种方法,前提是后端配置了允许跨域。
解决方案:
以下是具体代码:
// 给按钮绑定的点击事件
handelDownload() {
const {download_json: files} = this.articleInfo; //download_json为后端返回的数组对象 里面是包含了文件url和name的对象
if (!files) {
this.$notify.error({
title: '错误',
message: '没有可下载的附件'
});
} else {
files.forEach((i) => {
this.downloadFile(i.url, i.name)
})
}
},
// 下载方法
downloadFile(url, fileName, type) {
const xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'blob'; // 获取文件blob数据
xhr.onload = function () {
if (xhr.status !== 200) {
this.$notify.error({
title: '错误',
message: '下载出现错误'
});
return;
}
const newUrl = window.URL.createObjectURL(xhr.response); // 生成一个可用的临时url
const a = document.createElement('a'); // 生成a标签调用点击事件
a.setAttribute('href', newUrl);
a.setAttribute('target', '_blank');
a.setAttribute('download', fileName); // 自定义文件名
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
};
xhr.send();
},