Загрузите zip-поток в клиентском браузере из nodejs

#javascript #node.js #download #zip #blob

Вопрос:

Я хочу загрузить zip-файл, отправленный с моего сервера. Для создания архива я использовал библиотеку «архиватор». Вместо сохранения файла на сервере я отправил поток непосредственно клиенту.

 const archive = archiver('zip', {
    zlib: { level: 9 } // Sets the compression level.
});

archive.on('warning', function(err) {
    if (err.code === 'ENOENT') {
        // log warning
    } else {
        // throw error
        throw err;
    }
});

// good practice to catch this error explicitly
archive.on('error', function(err) {
    throw err;
});

// pipe archive as response
res.set({
    'Content-Type': 'application/zip',
})
archive.pipe(res);

// append files from a sub-directory, putting its contents at the root of archive
archive.directory(folderPath, false);

archive.finalize();
 

В клиенте я стараюсь сохранить его.

 const downloadImage = (folderName) => {

    const jqxhr = $.post("/api/download", { "folderName": folderName })
        .done((data) => {
            console.log("zip download");

            // var blob = new Blob([data], { type: "octet/stream" });
            // let d = unescape(encodeURIComponent(data));

            const blob = new Blob([data], { type: "application/zip" });
            saveFile(blob, "samples.zip")

        })
        .fail((err) => {
            console.log("Server return "   err.responseText);
        })
}

const saveFile = (blob, filename) => {
    const a = document.createElement('a');
    document.body.appendChild(a);
    const url = window.URL.createObjectURL(blob);
    a.href = url;
    a.download = filename;
    a.click();
    setTimeout(() => {
        window.URL.revokeObjectURL(url);
        document.body.removeChild(a);
    }, 0)
}
 

Проблема в том, что, хотя браузер сохраняет zip-файл, он поврежден, и я не могу распаковать его .

In browser data it looks like this

"PKu0003u0004u0014u0000u0008u0000u0008u0000nO�Ru0000u0000u0000u0000u0000u0000u0000u0000u0000u0000u0000u0000u000cu0000u0000u000012_59_28.png�yX�i�6�f9֨e���m�kY�JM�jꔥ�R���B�
�唕����(͔1�K����Ai����䊂����Z�=�s����x�{��C�����<����_mOʯݶu0016u0004u0002ɟ>��yu0010h�u0003u0008�
�4��u0011׬$�u000f/�N�r�B8f�amp;���xi ...

Я почти уверен, что ответ, полученный от сервера, верен, потому что, если я перейду в firefox -> параметры разработчика / сеть и посмотрю на полученный ответ, он будет закодирован браузером в base64 и действителен. Необработанный ответ от сервера-поток / байт.

Можете ли вы сказать мне, где я ошибаюсь?