使用archiver创建内存中的.zip,然后在节点服务器上使用koa将此文件发送到客户端

问题描述 投票:0回答:1

我(作为具有Koa框架的节点服务器),需要获取JSON blob,将其转换为扩展名为.json的文件,然后将其粘贴到zip存档中,然后将存档作为文件附件发送以响应来自客户端。

似乎这样做的方法是使用Archiver工具。最好我能理解,这样做的方法是创建一个存档,将json博客作为.json文件附加到它(它会自动在存档中创建文件吗?),然后将.zip“管道”到响应对象。 “管道”范式是我理解失败的地方,主要是因为没有得到这些文档所说的内容。

Archiver docs,以及一些stackoverflow answers,使用的语言对我来说意味着“通过管道(zip文件)将数据传输到客户端到HTTP响应对象.Koa docsctx.body可以直接设置为流,所以这是我试过的:

尝试1

    const archive = archiver.create('zip', {});
    ctx.append('Content-Type', 'application/zip');
    ctx.append('Content-Disposition', `attachment; filename=libraries.zip`);
    ctx.response.body = archive.pipe(ctx.body);
    archive.append(JSON.stringify(blob), { name: 'libraries.json'});
    archive.finalize();

逻辑:响应主体应设置为流,该流应该是归档流(指向ctx.body)。

结果:.zip文件在客户端下载,但是zip格式不正确(无法打开)。

尝试2

    const archive = archiver.create('zip', {});
    ctx.append('Content-Type', 'application/zip');
    ctx.append('Content-Disposition', `attachment; filename=libraries.zip`);
    archive.pipe(ctx.body);
    archive.append(JSON.stringify(blob), { name: 'libraries.json'});
    archive.finalize();

逻辑:将一个主体设置为流后,呃,“将流指向它”看起来确实很愚蠢,所以改为复制其他stackoverflow示例。

结果:与尝试1相同。

尝试3

基于https://github.com/koajs/koa/issues/944

    const archive = archiver.create('zip', {});
    ctx.append('Content-Type', 'application/zip');
    ctx.append('Content-Disposition', `attachment; filename=libraries.zip`);
    ctx.body = ctx.request.pipe(archive);
    archive.append(JSON.stringify(body), { name: 'libraries.json'});
    archive.finalize();

结果:ctx.request.pipe不是一个函数。

我可能没有正确阅读,但网上的所有内容似乎表明,做archive.pipe(some sort of client-sent stream)“神奇地起作用。” That's a quote of the archive tool example file,“流媒体魔术”是他们使用的词。

如何在内存中将JSON blob转换为.json,然后将.json附加到.zip然后发送到客户端并下载,然后可以成功解压缩以查看.json?

编辑:如果我在ctx.body之后调试archive.finalize(),它显示一个ReadableStream,这似乎是正确的。但是,它有一个让我担心的“路径”属性 - 它是我想知道的index.html - 在客户端的“响应预览”中,我看到了index.html的字符串化版本。该文件仍在下载.zip,所以我不太关心,但现在我想知道这是否相关。

编辑2:深入了解客户端的响应,似乎发回的数据是我们的index.html,所以现在我很困惑。

javascript node.js zip koa archiverjs
1个回答
0
投票

是的,您可以直接将ctx.body设置为流。 Koa将负责管道。无需手动管道任何东西(例如,除非您还想管道到日志)。

const archive = archiver('zip');

ctx.type = 'application/zip';
ctx.response.attachment('test.zip');
ctx.body = archive;

archive.append(JSON.stringify(blob), { name: 'libraries.json' });
archive.finalize(); 
© www.soinside.com 2019 - 2024. All rights reserved.