JSZip 文件无法解压 [英] JSZip files can't be unzipped

查看:123
本文介绍了JSZip 文件无法解压的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在一个 zip 文件中下载多个文件.当 zip 文件下载并尝试打开它时,我在 macos 上收到以下错误无法将测试扩展到下载(错误 1 ​​- 不允许操作)".

I want to download multiple files in a zip file. When the zip file downloads and I try opening it, I get the following error on macos 'unable to expand test into downloads (Error 1 - Operation not permitted)'.

下面是我使用jszip生成zip文件的代码

Below is the code I use to generate zip files using jszip

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 文件

I'm using filesaver.js to save the zip file

下载的 zip 文件只有 22 字节大,并且不包含在 for 循环中添加的内容.

The downloaded zip file is only 22 bytes large and doesn't contain the content added in the for loop.

编辑 3:在 generateAsync 中登录blob"没有返回正确的内容.在 for 循环中记录 zip 时确实如此.

EDIT 3: loggining 'blob' in generateAsync does not return the proper content. While logging zip in the for loop does.

编辑 4:我将 5 秒的 setTimeout 添加到 zip.generateAsync 并解决了该问题.5 秒后下载所有文件.似乎 zip.generateAsync 在 zip 文件添加到 for 循环之前触发.有没有一种解决方案可以在不使用不可靠的 settimeout 的情况下解决这个问题,也许是在 for 循环中添加所有文件后的回退?

EDIT 4: I added setTimeout of 5 seconds to zip.generateAsync and it fixed the issue. All files download after 5 seconds. It seems like zip.generateAsync triggers before the zip files are added in the for loop. Is there a solution that fixes this without using unreliable settimeout, perhaps a fallback once all files are added in the for loop?

推荐答案

reader.readAsText 是异步的:reader.onload 将被调用 after 其他一切.

reader.readAsText is asynchronous: reader.onload will be called after everything else.

在以下代码中:

for (...) {
  reader.onload = function() {
    // 3
  };
  reader.readAsText(...); // 1
}
// 2

您将在数组的每一项上循环并注册一个回调(1),然后在循环之外继续(2).最后,当文件阅读器结束它的工作时,3 将被执行.这就是为什么添加 setTimeout 来修复"问题:5 秒后,回调结束并填充 zip 对象.

You will loop on every item of your array and register a callback (1), then continue outside of the loop (2). Finally, when the file reader ends its job, 3 will be executed. That's why adding a setTimeout "fix" the issue: after 5 seconds, the callbacks ended and filled in the zip object.

修复:您可以异步读取每个 blob,并在调用 zip.generateAsync 之前等待所有读取结束.有一个更简单的方法:JSZip v3 读取 blob,因此您可以直接添加它.

The fix: you could read asynchronously every blob and wait for all reads to end before calling zip.generateAsync. There is an easier way: JSZip v3 reads blobs so you can directly add it.

假设 pages 是一个 FileList,你可以这样做:

Assuming pages is a FileList, you can do:

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 是一个专门的Blob,所以JSZip 可以读取它.

A File is a specialized Blob, so JSZip can read it to.

这篇关于JSZip 文件无法解压的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆