我正在创建一个需要从网站下载多个文件(图像和/或视频)的 Chrome 扩展程序。这些文件可能很大,所以我想向用户显示下载进度。经过一些研究,我发现目前可能的解决方案可能是:
- 使用 XMLHttpRequests 下载所有文件。
- 下载后,使用 JavaScript 库(例如 JSZip.js、zip.js)将所有文件压缩到一个存档中。
- 使用 SaveAs 对话框提示用户保存 zip。
我被困在第 2 段),如何压缩下载的文件?
为了理解,这是一个代码示例:
var fileURLs = ['http://www.test.com/img.jpg',...];
var zip = new JSZip();
var count = 0;
for (var i = 0; i < fileURLs.length; i++){
var xhr = new XMLHttpRequest();
xhr.onprogress = calculateAndUpdateProgress;
xhr.open('GET', fileURLs[i], true);
xhr.responseType = "blob";
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
var blob_url = URL.createObjectURL(response);
// add downloaded file to zip:
var fileName = fileURLs[count].substring(fileURLs[count].lastIndexOf('/')+1);
zip.file(fileName, blob_url); // <- here's one problem
count++;
if (count == fileURLs.length){
// all download are completed, create the zip
var content = zip.generate();
// then trigger the download link:
var zipName = 'download.zip';
var a = document.createElement('a');
a.href = "data:application/zip;base64," + content;
a.download = zipName;
a.click();
}
}
};
xhr.send();
}
function calculateAndUpdateProgress(evt) {
if (evt.lengthComputable) {
// get download progress by performing some average
// calculations with evt.loaded, evt.total and the number
// of file to download / already downloaded
...
// then update the GUI elements (eg. page-action icon and popup if showed)
...
}
}
上面的代码生成一个包含损坏的小文件的可下载存档。文件名同步还有一个问题:blob 对象不包含文件名,所以如果例如。fileURLs[0]
下载时间比fileURLs[1]
名称错误(倒置)要多。
注意:我知道 Chrome 有一个下载 API,但它在开发通道中,所以不幸的是它现在不是一个解决方案,我想避免使用 NPAPI 来完成这样一个简单的任务。