使用js进行文件下载的方法

    今天学到了一种使用js实现文件下载的方法,相比用表单进行下载要安全很多,不会有跳转问题,而且便于掌握下载进度.

大致思路

  1. 首先,使用ajax下载文件内容,读到内存中去. 这一步需要使用Blob对象存储文件内容;
  2. 然后建立一个隐藏的a标签,其链接指向内存中的地址. 这一步使用URL.createObjectUrl()方法拿到内存中的地址;
  3. 点击下载(直接调用a标签的click()方法即可),即从内存中下载到磁盘中去;

Blob对象的用法

构造函数

Blob(Content:array, options:Object)

Options

{type: type}: blob对象的MIME类型, 比如text/htmlapplication/octet-binary等等.

示例

1
var blob = new Blob(["test"], {type: "application/csv"})//MIME类型为csv的Blob对象

获取URL并实现下载

示例

1
2
3
4
5
6
7
8
var blob = new Blob(["test"], {type: "application/csv"});
var a = document.createElement("a");
a.href = URL.createObjectURL(blob);//创建指向此blob的链接
a.download = "test.csv";
//输出类似于blob:http://$website/fsadjlfsdjl 这样的字符串
document.body.append(a);
a.click();//实现下载
a.remove();

从远端下载

如果要从远端下载文件,先使用ajax下载数据, 在拿到数据以后再使用blob做处理就好.

示例代码

1
2
3
4
5
6
7
8
9
10
//使用jquery
$.get(url, function(data){
var blob = new Blob([data], {type: "application/csv"});//加一个方括号,data会直接转为字符串, 这里有一个问题,就是jquery本身会将data作为String处理
var a = document.createElement("a");
a.href = URL.createObjectURL(blob);
a.download = "download.csv";
document.body.appendChild(a);
a.click();
a.remove();
});

考虑到jQuery的问题以及兼容性等, 以及不能转为字符串的情况, 可以使用传统的XMLHttpRequest发送请求(),代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//使用XMLHttpRequest
var httpRequest;
if (window.XMLHttpRequest) {
httpRequest = new XMLHttpRequest();
} else if (window.ActiveXObject) { // 兼容ie6及之前的版本
httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
}
httpRequest.open("GET", url/*url地址*/, true);
httpRequest.responseType = "blob";
httpRequest.onload = function () {
if (this.status === 200 ) {
var blob = this.response;
var reader = new FileReader();
reader.readAsDataURL(blob);
reader.onload = function(ev) {//读入完成事件
var a = document.createElement("a");
a.href = ev.target.result;//读取结果
a.download = "download.csv";
document.body.appendChild(a);
a.click();
a.remove();
}
}
}
httpRequest.send();

其他用法

还可以使用此方法来动态加载图片, 只需要把blob对象的URL给到img的src里就好, 其他资源也一样.