我想在zip文件中下载多个文件。当zip文件下载并且我尝试打开它时,我在macos'无法将测试扩展到下载(错误1 - 不允许操作)'时收到以下错误。
以下是我用jszip生成zip文件的代码
var pages = $pagesComponentsDownloadSavetoFileinput[0].files;
var zip = new JSZip();
for(let i = 0; i < pages.length; i++) {
let reader = new FileReader();
reader.onload = function() {
zip.file(pages[i].name, pages[i].content);
console.log(zip) // returns proper file name and content objects
}
reader.readAsText(pages[i]);
}
window.setTimeout(function() { // setTimeout fixes the issue
zip.generateAsync({type:"blob"}).then(function(blob) {
console.log(blob); // returns Blob(22) {size: 22, type: "application/zip"} with no content
saveAs(blob, "TESTING.zip");
}, function (err) {
console.log(err)
});
}, 5000);
编辑:我正在使用filesaver.js保存zip文件
EDIT2:下载的zip文件只有22个字节大,不包含for循环中添加的内容。
编辑3:在generateAsync中记录'blob'不会返回正确的内容。虽然在for循环中记录zip。
编辑4:我为zip.generateAsync添加了5秒的setTimeout,它解决了这个问题。 5秒后下载所有文件。在for循环中添加zip文件之前,似乎是zip.generateAsync触发器。是否有一个解决方案可以在不使用不可靠的settimeout的情况下修复此问题,在for循环中添加所有文件后可能会出现回退?
答案 0 :(得分:0)
reader.readAsText
是异步的:{/ 1>}在之后将被称为。
在以下代码中:
reader.onload
您将遍历数组的每个项目并注册回调(for (...) {
reader.onload = function() {
// 3
};
reader.readAsText(...); // 1
}
// 2
),然后继续循环(1
)。最后,当文件阅读器结束其作业时,将执行2
。
这就是为什么添加3
“修复”问题的原因:5秒后,回调结束并填入setTimeout
对象。
修复:您可以异步读取每个blob并等待所有读取结束,然后再调用zip
。有一种更简单的方法:JSZip v3读取blob,以便您可以直接添加它。
编辑:
假设zip.generateAsync
是FileList,您可以执行以下操作:
pages
for(let i = 0; i < pages.length; i++) {
// here, pages[i] is a File (https://developer.mozilla.org/en-US/docs/Web/API/File)
zip.file(pages[i].name, pages[i]);
}
zip.generateAsync({type:"blob"}).then(function(blob) {...});
是一个专门的File
,因此JSZip可以将其读取。