最近博主做的项目对文件下载的方式有需求,因此也整理了部分资料以供分享。

a标签

这是我们最熟悉的方式。但是对于浏览器可以默认打开的格式:pdf、图像等,就不是默认下载了。
所以我们可以使用html5新增的download属性,默认下载。

1
<a href='file.js'>file.js</a>

这种方式有两个缺点:
1、兼容性不好
2、href必须是同源地址,不然download属性不生效,也是默认打开。也就是跨域无效。

决定是否能下载取决于:

1
2
3
4
//表明文件类型
header( "Content-Type: video/mp4" );
//类型为下载,同时设置下载文件名
header("Content-Disposition: attachment;filename=qwe.mp4");

window.location.href

使用window.location.href = ‘’也可以获取资源。不能下载默认打开格式也是一样的,不过可以通过
window.open() 打开新页面

createObjectURL

Gecko 2.0 (Firefox 4 / Thunderbird 3.3 / SeaMonkey 2.1)引入了对DOM window.URL.createObjectURL() 和 window.URL.revokeObjectURL() 方法的支持。这使得你可以创建用于引用任何数据的简单URL字符串,也可以引用一个包括用户电脑上的本地文件的DOM File对象。

createObjectURL和 revokeObjectURL

这个对象URL是一个标识File对象的字符串。每次你调用window.URL.createObjectURL(),就会产生一个唯一的对象URL,即使是你对一个已创建了对象URL的文件再次创建一个对象URL。每个创建了的对象URL必须要释放。当文档关闭时,它们会自动被释放。如果你的网页要动态使用它们,你需要显式调用 window.URL.revokeObjectURL()来释放它们。

1
var blobObject = new Blob(["I scream. You scream. We all scream for ice cream."]);

但是这种方式在IE存在问题,你们看ie的createObjectURL和chrome不一样,chrome带了域名,而ie不带域名。
blob:242CACD6-06D5-4145-A6DA-55DBE47409DB
blob:null/242CACD6-06D5-4145-A6DA-55DBE47409DB
所以要采用ie独有的方法window.navigator.msSaveOrOpenBlob 或者window.navigator.msSaveBlob。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//解决浏览器兼容性问题
if('msSaveOrOpenBlob' in navigator){
// Microsoft Edge and Microsoft Internet Explorer 10-11
window.navigator.msSaveOrOpenBlob(fileBlob, name);
}else{
// standard code for Google Chrome, Mozilla Firefox etc
let dom = document.createElement('a');
dom.download = name;
dom.style.display = 'none';
let url = URL.createObjectURL(fileBlob);
dom.href = url;
document.body.appendChild(dom);
dom.click();
URL.revokeObjectURL(url);
}

我运用到这个需求是我请求资源必须在header的token中携带自己的身份信息,所以我不能使用a标签进行请求。必须使用请求获取二进制blob数据。