简体   繁体   English

jszip 可以解压文件但不能解压文件夹

[英]jszip can unzip files but not folders

I would like to download and unzip a folder with JSZip , I installed it with this npm package .我想用JSZip下载并解压缩一个文件夹,我用这个npm 包安装了它。 JSZip is unable to do so, complaining about corrupted zip or unexpected signature. JSZip 无法这样做,抱怨损坏的 zip 或意外的签名。

There are many questions related to jszip.关于jszip的问题很多。 None of them answer my specific question, but for the sake of completeness, I'm listing a few references here:他们都没有回答我的具体问题,但为了完整起见,我在这里列出了一些参考资料:

As a test scenario, I have created two zip files, called folder.zip and text.zip .作为测试场景,我创建了两个 zip 文件,分别称为folder.ziptext.zip text.zip is a zipped txt file, folder.zip is a zipped folder, containing a txt file. text.zip是一个压缩的 txt 文件, folder.zip是一个压缩的文件夹,包含一个 txt 文件。 Both have been zipped by the command line, in Ubuntu.两者都已在 Ubuntu 中通过命令行压缩。

I'm hosting them with the npm package serve .我用npm 包 serve托管它们。 They are accessible on localhost: http://localhost:5000/test.zip它们可以在本地主机上访问: http://localhost:5000/test.zip

Here is my code, it's typescript, the compiled Javascript is executed with node:这是我的代码,它是打字稿,编译后的 Javascript 是用节点执行的:

import axios from 'axios';
import * as JSZip from 'jszip';
axios.get(
    "http://localhost:5000/text.zip",
    //"http://localhost:5000/folder.zip",
    { responseType: "blob" })
    .then((response) => {

        let zip = new JSZip();
        zip.loadAsync(response.data).then((value) => {
            console.log('jszip unzipped response.data');
            value.forEach((path, file) => {
                console.log(path);
            })
        }).catch((e) => {
            console.log(`jszip failed on response.data: ${e}`);
        })

        let buffer = Buffer.from(response.data, 'binary');
        zip.loadAsync(buffer).then((value) => {
            console.log('jszip unzipped buffer');
            value.forEach((path, file) => {
                console.log(path);
            })
        }).catch((e) => {
            console.log(`jszip failed on buffer: ${e}`);
        })

    }).catch((reason) => {
        console.log(`axios request failed: ${reason}`);
    })

The text.zip file can be unzipped without problems. text.zip文件可以text.zip地解压缩。 But when I try to unzip the folder, it fails.但是当我尝试解压缩文件夹时,它失败了。 The error message is:错误信息是:

jszip failed on response.data: Error: Corrupted zip or bug: unexpected signature (\x00\x50\x4B\x07, expected \x50\x4B\x03\x04)

For comparison, I'm doing the same with adm-zip .为了比较,我对adm-zip做同样的事情。 This works for both the zipped file and the zipped folder.这适用于压缩文件和压缩文件夹。 adm-zip only works when it is given a buffer though.不过,adm-zip 仅在给定缓冲区时才有效。 That's why I also tried passing a buffer to jszip.这就是为什么我还尝试将缓冲区传递给 jszip。

import axios from 'axios';
import * as AdmZip from 'adm-zip';
axios.get(
    "http://localhost:5000/folder.zip",
    { responseType: "blob" })
    .then((response) => {


        let buffer = Buffer.from(response.data, 'binary');
        let admzip = new AdmZip(buffer);
        let zipEntries = admzip.getEntries();
        zipEntries.forEach(element => {
            console.log(element.entryName);
        })

    }).catch((reason) => {
        console.log(`axios request failed: ${reason}`);
    })

Seems JSZip is a bit incomplete yet, according to it bugtracker (lots and generic errors present yet).根据 bugtracker 的说法,JSZip 似乎有点不完整(目前还存在大量和一般错误)。 About your error, there is another very similar: https://github.com/Stuk/jszip/issues/489 but i'm sure there are anothers.关于您的错误,还有另一个非常相似的错误: https : //github.com/Stuk/jszip/issues/489但我确定还有其他错误。

So answer seems to be: JSZip is yet not-production-ready library at least for generic cases, and does not support it yet.所以答案似乎是: JSZip 至少对于通用情况来说还不是生产就绪的库,并且还不支持它。

The problem seems to be related to arraybuffer vs blob .问题似乎与arraybufferblob

Depending on the configuration of the http request, the data field in the axios response will contain different values.根据 http 请求的配置, axios responsedata字段会包含不同的值。

In the following code:在以下代码中:

let responseType = 'blob'

axios.get(
    "http://localhost:5000/folder.zip",
    { responseType: responseType })
    .then((response) => {
        console.log(typeof(response.data);
        //...

the following pairs are possible:以下对是可能的:

  • blob -> string , adm-zip works, jszip does not work blob -> string ,adm-zip 有效,jszip 无效
  • arraybuffer -> object , both work arraybuffer -> object ,两者都有效
  • not specified -> string , adm-zip works, jszip does not未指定 -> string ,adm-zip 有效,jszip 无效

If the data has type string , adm-zip only works if it is manually converted into a Buffer .如果数据的类型为string ,则 adm-zip 仅在手动转换为Buffer时才有效。

If the result type is already a buffer, both work without any conversions.如果结果类型已经是缓冲区,则两者都无需任何转换即可工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM