Web サイトから複数のファイル (画像やビデオ) をダウンロードする必要がある Chrome 拡張機能を作成しています。これらのファイルは巨大なサイズになる可能性があるため、ダウンロードの進行状況をユーザーに表示したいと考えています。いくつかの調査の結果、現在考えられる解決策は次のとおりであることがわかりました。
- XMLHttpRequests ですべてのファイルをダウンロードします。
- ダウンロードしたら、すべてのファイルを JavaScript ライブラリ (例: JSZip.js、zip.js) で 1 つのアーカイブに圧縮します。
- 名前を付けて保存ダイアログで 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 を使用することは避けたいと思います。