jszip可以解压文件但不能解压文件夹
jszip can unzip files but not folders
我想用 JSZip, I installed it with this npm package 下载并解压一个文件夹。 JSZip 无法这样做,抱怨 zip 损坏或意外签名。
关于jszip的问题很多。 None 其中回答了我的具体问题,但为了完整起见,我在这里列出了一些参考资料:
- JSZip files can't be unzipped
- JSZip unzipping error
- Can't download folder with JSZip
作为测试方案,我创建了两个 zip 文件,名为 folder.zip
和 text.zip
。 text.zip
是一个压缩的 txt 文件,folder.zip
是一个压缩的文件夹,包含一个 txt 文件。两者都已通过命令行压缩,在 Ubuntu.
我用 npm package serve 托管他们。它们可以在本地主机上访问:http://localhost:5000/test.zip
这是我的代码,它是打字稿,编译后的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}`);
})
text.zip
文件可以顺利解压。但是当我尝试解压缩文件夹时,它失败了。
错误信息是:
jszip failed on response.data: Error: Corrupted zip or bug: unexpected signature (\x00\x50\x4B\x07, expected \x50\x4B\x03\x04)
为了比较,我对 adm-zip 做同样的事情。
这适用于压缩文件和压缩文件夹。
adm-zip 仅在给定缓冲区时才起作用。这就是为什么我也尝试将缓冲区传递给 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}`);
})
根据 bugtracker 的说法,JSZip 似乎还有点不完整(目前还存在很多一般性错误)。关于您的错误,还有一个非常相似:https://github.com/Stuk/jszip/issues/489 但我确定还有其他错误。
所以答案似乎是:至少对于一般情况,JSZip 还不是生产就绪的库,并且还不支持它。
问题似乎与 arraybuffer
和 blob
有关。
根据 http 请求的配置,axios
response
中的 data
字段将包含不同的值。
在下面的代码中:
let responseType = 'blob'
axios.get(
"http://localhost:5000/folder.zip",
{ responseType: responseType })
.then((response) => {
console.log(typeof(response.data);
//...
以下对是可能的:
blob
-> string
,adm-zip 有效,jszip 无效
arraybuffer
-> object
,两者都有效
- 未指定 ->
string
,adm-zip 有效,jszip 无效
如果数据的类型为 string
,adm-zip 仅在手动转换为 Buffer
时才有效。
如果结果类型已经是缓冲区,则两者都无需任何转换即可工作。
我想用 JSZip, I installed it with this npm package 下载并解压一个文件夹。 JSZip 无法这样做,抱怨 zip 损坏或意外签名。
关于jszip的问题很多。 None 其中回答了我的具体问题,但为了完整起见,我在这里列出了一些参考资料:
- JSZip files can't be unzipped
- JSZip unzipping error
- Can't download folder with JSZip
作为测试方案,我创建了两个 zip 文件,名为 folder.zip
和 text.zip
。 text.zip
是一个压缩的 txt 文件,folder.zip
是一个压缩的文件夹,包含一个 txt 文件。两者都已通过命令行压缩,在 Ubuntu.
我用 npm package serve 托管他们。它们可以在本地主机上访问:http://localhost:5000/test.zip
这是我的代码,它是打字稿,编译后的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}`);
})
text.zip
文件可以顺利解压。但是当我尝试解压缩文件夹时,它失败了。
错误信息是:
jszip failed on response.data: Error: Corrupted zip or bug: unexpected signature (\x00\x50\x4B\x07, expected \x50\x4B\x03\x04)
为了比较,我对 adm-zip 做同样的事情。 这适用于压缩文件和压缩文件夹。 adm-zip 仅在给定缓冲区时才起作用。这就是为什么我也尝试将缓冲区传递给 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}`);
})
根据 bugtracker 的说法,JSZip 似乎还有点不完整(目前还存在很多一般性错误)。关于您的错误,还有一个非常相似:https://github.com/Stuk/jszip/issues/489 但我确定还有其他错误。
所以答案似乎是:至少对于一般情况,JSZip 还不是生产就绪的库,并且还不支持它。
问题似乎与 arraybuffer
和 blob
有关。
根据 http 请求的配置,axios
response
中的 data
字段将包含不同的值。
在下面的代码中:
let responseType = 'blob'
axios.get(
"http://localhost:5000/folder.zip",
{ responseType: responseType })
.then((response) => {
console.log(typeof(response.data);
//...
以下对是可能的:
blob
->string
,adm-zip 有效,jszip 无效arraybuffer
->object
,两者都有效- 未指定 ->
string
,adm-zip 有效,jszip 无效
如果数据的类型为 string
,adm-zip 仅在手动转换为 Buffer
时才有效。
如果结果类型已经是缓冲区,则两者都无需任何转换即可工作。