JSZIP может распаковать файлы, но не папки - PullRequest
1 голос
/ 28 февраля 2020

Я хочу скачать и распаковать папку с JSZip , я установил ее с этим npm пакетом . JSZip не может этого сделать, жалуется на испорченный zip или неожиданную подпись.

Есть много вопросов, связанных с jszip. Никто из них не отвечает на мой конкретный c вопрос, но ради полноты я приведу здесь несколько ссылок:

В качестве тестового сценария я создал два zip-файла, которые называются folder.zip и text.zip. text.zip - это заархивированный текстовый файл, folder.zip - это заархивированная папка, содержащая текстовый файл. Оба были заархивированы из командной строки в Ubuntu.

Я размещаю их с npm обслуживанием пакета . Они доступны на локальном хосте: 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 . Это работает как для zip-файла, так и для 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}`);
    })

Ответы [ 2 ]

1 голос
/ 28 февраля 2020

Кажется, JSZip еще немного неполон, по словам багтрекер (лотов и общих c ошибок пока нет). Что касается вашей ошибки, есть еще одно очень похожее: https://github.com/Stuk/jszip/issues/489, но я уверен, что есть и другие.

Так что ответ, похоже, таков: JSZip еще не готова к производству в хотя бы для обобщенных c случаев и пока не поддерживает его.

0 голосов
/ 28 февраля 2020

Проблема, похоже, связана с arraybuffer против blob.

В зависимости от конфигурации http-запроса, поле data в axios response будет содержать различные значения .

В следующем коде:

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.

Если тип результата уже является буфером, оба работают без каких-либо преобразований.

...