Github page原文链接:https://aak1247.github.io/js-download-blob.html
博客地址: 黑境-aak1247的博客
今天学到了一种使用js实现文件下载的方法,相比用表单进行下载要安全很多,不会有跳转问题,而且便于掌握下载进度.
大致思路
- 首先,使用ajax下载文件内容,读到内存中去. 这一步需要使用Blob对象存储文件内容;
- 然后建立一个隐藏的a标签,其链接指向内存中的地址. 这一步使用URL.createObjectUrl()方法拿到内存中的地址;
- 点击下载(直接调用a标签的click()方法即可),即从内存中下载到磁盘中去;
Blob对象的用法
构造函数
Blob(Content:array, options:Object)
Options
{type: type}
: blob对象的MIME类型, 比如text/html
或application/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里就好, 其他资源也一样.