Ok, this is my working solution of downloading files at once with setTimeout()
var fileUrls = [...];
var tempLink = document.createElement('a');
document.body.appendChild(tempLink);
downloadMultipleFiles(fileUrls);
function downloadMultipleFiles(fileUrls) {
setTimeout(function() {
var fileIndex = fileUrls.length*1-1*1;
var fileUrl = fileUrls[fileIndex];
tempLink.setAttribute('href', fileUrl);
tempLink.setAttribute('download', fileUrl.split('/')[fileUrl.split('/').length*1-1*1]);
tempLink.click();
if(fileIndex > -1) {
fileUrls.splice(fileIndex, 1);
}
if(fileUrls.length > 0) {
downloadMultipleFiles(fileUrls);
} else {
document.body.removeChild(tempLink);
}
}, 200); // if less than 200, not all files are downloaded in Firefox
}
And this my working solution of zipping files without server side using jszip mentioned by @Kaiido:
// prepare blobs with data of files when load a page
var fileUrls = [...];
var blobs = [];
for(i = 0; i < fileUrls.length; i++) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if(this.readyState == 4 && this.status == 200) {
var filename = this.responseURL.split('/')[this.responseURL.split('/').length*1-1*1];
var mimeType = this.getResponseHeader('Content-Type');
blobs.push([filename, new Blob([this.response], {type: mimeType})]);
}
};
xhttp.open('GET', fileUrls[i], true);
xhttp.responseType = "arraybuffer";
xhttp.send();
}
document.getElementsByClassName('.download_all_link')[0].addEventListener('click', function(){
if(this.id != '') {
var zip = new JSZip();
var folder = zip.folder('subfolder');
for(i = 0; i < blobs.length; i++) {
folder.file(blobs[i][0], blobs[i][1]);
}
zip.generateAsync({type : 'blob'})
.then(zip_blob => {
download_all.href = URL.createObjectURL(zip_blob);
});
// as we don't know when zip is ready,
// we check link href every 500 ms by using recursive function with setTimeout()
checkHref(this);
}
});
}
function checkHref(thisLink) {
setTimeout(function() {
// when zip is ready we click by the link again to download zip
if(~thisLink.href.indexOf('blob:')) {
thisLink.download = 'myfiles.zip';
thisLink.id = ''; // to prevent zipping again
thisLink.click(); // to download zip
} else {
checkHref(thisLink);
}
}, 500);
}
i*333
for the 2nd argument. – Stratocumulusdocument.body.appendChild(a)
before you click() it. you might also try a synthetic click event instead of justa.click()
. does a simple example (no loop) work in FF? – Stratocumulus