Javascript 如何在JS中在包括Firefox在内的浏览器中下载10多个文件

Javascript 如何在JS中在包括Firefox在内的浏览器中下载10多个文件,javascript,Javascript,我尝试使用以下代码一次下载多个文件: var urls = [...]; for(var i = 0; i < urls.length; i++) { var tempLink = document.createElement('a'); tempLink.setAttribute('href', urls[i]); tempLink.setAttribute('download', urls[i].split('/')[urls[i].split('/').l

我尝试使用以下代码一次下载多个文件:

var urls = [...];

for(var i = 0; i < urls.length; i++) {

    var tempLink = document.createElement('a');
    tempLink.setAttribute('href', urls[i]);
    tempLink.setAttribute('download', urls[i].split('/')[urls[i].split('/').length*1-1*1]);
    tempLink.click();
}
var url=[…];
对于(var i=0;i
还有两个问题:

1。Chrome和Opera一次只下载10个文件

2.在Firefox中,代码根本不起作用

如何解决这两个问题


另外,我知道如何使用服务器端压缩所有文件,但我对JS解决方案感兴趣,该解决方案适用于没有服务器端的静态网站

好的,这是我使用
setTimeout()立即下载文件的工作解决方案


这是我的工作解决方案,无需服务器端即可压缩文件,使用:

//加载页面时准备包含文件数据的blob
var fileurl=[…];
var blobs=[];
对于(i=0;i{
下载\u all.href=URL.createObjectURL(zip\u blob);
});
//因为我们不知道zip什么时候准备好,
//我们使用带有setTimeout()的递归函数每隔500毫秒检查一次link href
checkHref(这个);
}
});
}
函数checkHref(此链接){
setTimeout(函数(){
//当zip准备好后,我们再次点击链接下载zip
if(~thisLink.href.indexOf('blob:')){
thisLink.download='myfiles.zip';
thisLink.id='';//防止再次压缩
thisLink.click();//下载zip
}否则{
checkHref(thisLink);
}
}, 500);
}

与其下载多个文件,最好是将它们全部打包到一个文件中。 例如,您可以从所有这些文件生成一个zip文件

既然您声明服务器端解决方案不是您的选择,而是您的所有文件都托管在您的域中,那么我可以建议您首先通过AJAX获取您的所有文件(因为这些是已经加载到页面上的图像,它们甚至不需要再次实际下载,而只需要从缓存中收集)然后在前端构建zip文件

//所有图像都来自wikimedia
常量URL=3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3,'/2/2b/Mormantulluiamzapellea284%29.jpg/360px-MormantulLuiAmzaPellea_%284%29.JPG',“/f/f8/Launch_LAWRENCE_LCCN2014710971.tif/lossy-page1-174px-Launch_LAWRENCE_LCCN2014710971.tif.JPG']
.map((url)=>'https://upload.wikimedia.org/wikipedia/commons/thumb“+url”);
fetchBlob(URL)
.然后(打包)
.然后((zipFile)=>dl.href=URL.createObjectURL(zipFile));
函数fetchBlob(URL){
回报你的承诺(
url.map((url)=>
获取(url)
.然后((resp)=>resp.blob())
.然后((blob)=>{
//存储文件名
blob.name=url.slice(url.lastIndexOf('/')+1)
返回斑点;
})
)
);
}
功能包(BLOB){
const-zip=new-JSZip();
const folder=zip.folder('my_images');
forEach((blob)=>folder.file(blob.name,blob));
返回zip.generateAsync({type:“blob”});
}


下载
我已经在chrome上下载了1000个这样的文件,但是我不得不使用setTimeout和半慷慨的计时来错开下载,以确保它没有备份(没有回调使它真正异步)。为第二个参数输入类似于
i*333
的超时。@dandavis谢谢!Firefox呢?如果您可以访问服务器,最好向服务器发送一个要下载的文件列表,让服务器将它们压缩在一起,然后发送压缩后的文件。即使它只是返回文件位置供您下载“手动”加载在您的脚本中,这比试图管理多次下载之间的时间延迟要好。例如,在C#:中,当然要使用您需要的语言。@computercarguy是的,我知道如何压缩,但我想为没有服务器端的静态网站找到一个解决方案。下载的文件来自哪里?浏览器的内存,如链接问题中所示?同一来源(如果服务器端真的不可用,那么您可以使用AJAX预取它们并将它们打包到内存中)?其他域?(在这种情况下,您甚至无法从Firefox加载它们)。
XMLHttpRequest
也可以直接获取Blob,将
响应类型设置为
“Blob”
intead of
“arraybuffer”
,这样就不需要自己生成新的Blob,而且还避免了无需使用太多内存(即使稍后会被垃圾收集)谢谢!还有一个问题:如何将文件直接打包到zip,而不需要中间子文件夹,如回答中的
.folder('my_images')
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
}
// 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);
}