前端在进行文件下载时,一般会用四种方法,对它们做个梳理。
一 location.href
window.location.href = url;
二 window.open()
window.open(url, '_self');
三 <a>标签
const a = document.createElement('a');
a.href = url;
a.download = fileName;
document.body.appendChild(a);
a.click();
a.remove();
四 fetch/axios + <a>标签
当接口需要token、鉴权、请求头时,会使用这种方式,也是最好最常用的的方式。
axios.post(url, data, { responseType: 'blob' })
.then(res => {
const blob = new Blob([res.data], {
type: res.headers['content-type']
});
const href = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = href;
a.download = fileName;
a.click();
a.remove();
URL.revokeObjectURL(href); // 释放临时内存
})
总结
文件下载的基本流程是:前端拿到url发起跳转,浏览器调用了资源接口请求,后端响应头有Content-Disposition:attachment,这个响应头规定响应信息以附件的形式下载并保存到本地。
从中可以出,文件下载功能的本质是:后端通过接口响应头对浏览器处理响应信息的方式进行控制,前端只是发起了请求而已。
而给a标签加上download属性的目的是,如果后端没有返回Content-Disposition: attachment,浏览器默认会根据文件类型决定是预览还是下载,如果加上download属性,浏览器才会被指示去执行“下载”操作,而不是“预览”操作。