一、 为什么a标签无法下载,无法重命名?
这就与 a 标签的 href 有很大的关系, href 属性的地址必须是 同源 URL,否则,download 就会不起作用。
- 同源 URL 会进行 下载 操作
- 非同源 URL 会进行 导航 操作
- 非同源的资源 仍需要进行下载,那么可以将其转换为
blob: URL
形式
二、a 标签属性介绍
<a> 的 download 属性是HTML5新增的属性,它可以使 a 标签的 href 属性进行下载,download 属性为下载后的 文件名,但是:
- 这个值可能会通过 JavaScript 进行动态修改
- 或者 Content-Disposition 中指定的 download 属性优先级高于 a.download
三、下载方法
注意:以下3种方式,是对文件的 链接地址 所写的方案(例:http://127.0.0.1:3000/1.jpg)
*[HTML]: 超文本标记语言
1、同源URL
- 静态方式
<a href="http://127.0.0.1:3000/1.jpg" download="1.jpg">下载</a>
- 动态方式
function aTagDownload(url, filename){
const a = document.createElement("a"); // 创建 a 标签
a.href = url; // 下载路径
a.download = filename; // 下载属性,文件名
a.style.display = "none"; // 不可见
document.body.appendChild(a); // 挂载
a.click(); // 触发点击事件
document.body.removeChild(a); // 移除
}
2、非同源URL
- Blob 方式
function download(path, fileName=''){
if (!fileName) fileName = '123.jpg'
fetch(path).then(res =>
res.blob()
).then((blob) => {
let objectUrl = URL.createObjectURL(blob); // 创建 url 对象
aTagDownload(objectUrl,fileName); // 调用 上面 [2] 动态方式
}).catch((err) => {
console.log('Request Failed', err)
})
}
四、接口返回文件流(例:Excel、word、PDF文件)
// excelExport后台接口
// 请求接口时需要增加 responseType: `blob`,不然下载的文件内容会乱码
excelExport(params).then(res => {
if (!res) return;
excelDownload(res) // 调用下载方法 res 二进制流
});
function excelDownload(res){
let fileReader = new FileReader();
fileReader.onload = function() {//对于blob文件流进行转换,拿到接口返回的状态码以及提示语
try {
let jsonData = JSON.parse(this.result)
if(jsonData.status == 403){ // 403:禁止访问
logOut(jsonData.reason); // logOut 退出登录
return;
}
} catch (err) {
}
};
fileReader.readAsText(res)
// 这个window.fileName我是在接口响应处获取的
// window.fileName = response.headers['content-disposition'] && response.headers['content-disposition'].split(`filename=`)[1];
const fileName = window.decodeURI(window.fileName);
const suffix = fileName.split('.')[1]; // 文件类型
let blob = new Blob([res], { type: FileType[suffix] }); // 创建 blob 对象
let objectUrl = URL.createObjectURL(blob); // 创建 url 对象
aTagDownload(objectUrl,fileName) // 调用 上面 [2] 动态方式
}