0%

使用Js下载文件(模仿https://mega.io/)

如果你用过Maga 网盘,那你可能发现它的文件下载方式不是直接用浏览器下载,而是先在网页中下载,下载完成后才调起浏览器的下载,比较酷。

原理就是它用了 blob 进行文件的下载之后再输出出来。我朋友 ZJINH 写了一个网盘软件中就实现了这个功能,他在群里讨论这个功能的同时也分享了代码,我的友链中有他的博客地址,欢迎大家访问(还能白嫖到他网盘客户端的源码)。

运行效果

代码如下

实现

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
function download(url, progress, callback, error) {
const xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.abort();
xhr.addEventListener(
'progress',
function (e) {
if (e.lengthComputable) {
progress && progress(e.total, e.loaded);
}
},
false
);
xhr.responseType = 'blob';
xhr.onload = () => {
if (xhr.status === 200) {
callback(xhr.response);
}
};
xhr.onerror = (e) => {
error && error(e);
};
xhr.send();
return xhr;
}

代码很好看,这儿不多做分析,关键的地方是 xhr.responseType = 'blob'; 用 blob 的方式获取资源。

补充

他没有给出全部的代码,callback 返回的是一个 blob 对象,我这儿补充一下。让代码跑起来

1
2
3
4
5
6
7
8
9
10
function blobDownload(blob, fileName) {
let a = document.createElement('a');
a.style = 'display: none';
document.body.appendChild(a);
let url = window.URL.createObjectURL(blob);
a.href = url;
a.download = fileName;
a.click();
window.URL.revokeObjectURL(url);
}

运行

1
2
3
4
5
6
7
8
9
10
11
12
let url = 'https://files.itnote.me/Software/npp.7.8.5.Installer.exe';

download(
url,
(total, loaded) => {
console.log('total, loaded', total, loaded);
},
(callback) => {
console.log('callback', callback);
blobDownload(callback, 'npp.7.8.5.Installer.exe');
}
);