概述
最近项目中做了一个关于文件下载的功能的时候,由于文件下载的格式不定,所以经常出现使用a标签下载的时候,直接就浏览器打开了,而浏览器不支持的类型,就直接是下载,因此为了兼容所有文件类型,这里总结下完整解决方案。
原因
对于图片、pdf、txt等浏览器支持直接打开预览的文件,则不会进行下载
解决办法
模拟发送http请求,将文件链接转换成文件流,然后使用a标签download属性进行下载。
具体实现
关于发送请求的工具可以使用fetch,axios,jquery都行,重点指定返回数据格式类型为blob就行。
function downloadImg(url,name){
// 方法1
fetch(url).then(res =>{
console.log(res)
return res.blob();
}).then(blob => {
console.log(blob)
const a = document.createElement('a');
a.download = name;
a.href = URL.createObjectURL(blob);
a.click();
URL.revokeObjectURL(a.href);
a.remove();
});
// 方法2
// axios.get(url).then(res=>{
// console.log(res)
// const a = document.createElement('a');
// a.download = name;
// const blob = new Blob([res.data],{type :res.headers['content-type']});
// console.log(blob)
// a.href = URL.createObjectURL(blob);
// a.click();
// URL.revokeObjectURL(a.href);
// a.remove();
// })
}
downloadImg(图片地址, 下载文件名);
关于blob url
看了很多关于这方面的解释,下面的比较好懂点:
Blob URL/Object URL 是一种伪协议,允许 Blob 和 File 对象用作图像、下载二进制数据链接等的 URL 源。在浏览器中,我们使用 URL.createObjectURL 方法来创建 Blob URL,该方法接收一个 Blob 对象,并为其创建一个唯一的 URL,其形式为 blob:<origin>/<uuid>,对应的示例如下blob:http://localhost:3000/53acc2b6-f47b-450f-a390-bf0665e04e59
浏览器内部为每个通过 URL.createObjectURL 生成的 URL 存储了一个URL → Blob 映射。因此,此类 URL 较短,但可以访问 Blob。生成的 URL 仅在当前文档打开的状态下才有效。它允许引用 <img>、<a> 中的 Blob,但如果你访问的 Blob URL 不再存在,则会从浏览器中收到 404 错误。
上述的 Blob URL 看似很不错,但实际上它也有副作用。 虽然存储了 URL → Blob 的映射,但 Blob 本身仍驻留在内存中,浏览器无法释放它。映射在文档卸载时自动清除,因此 Blob 对象随后被释放。但是,如果应用程序寿命很长,那么 Blob 在短时间内将无法被浏览器释放。因此,如果你创建一个 Blob URL,即使不再需要该 Blob,它也会存在内存中。
针对这个问题,你可以调用 URL.revokeObjectURL(url) 方法,从内部映射中删除引用,从而允许删除 Blob(如果没有其他引用),并释放内存。