简体   繁体   English

将SailsJS后端的zip文件传输到React Redux前端

[英]Piping zip file from SailsJS backend to React Redux Frontend

I have a SailsJS Backend where i generate a zip File, which was requested by my Frontend, a React App with Redux. 我有一个SailsJS后端,我在其中生成一个zip文件,这是我的前端(带有Redux的React App)请求的。 I'm using Sagas for the Async Calls and fetch for the request. 我正在使用Sagas进行异步调用并提取请求。 In the backend, it tried stuff like: 在后端,它尝试了以下操作:

//zipFilename is the absolute path 
res.attachment(zipFilename).send();

or 要么

res.sendfile(zipFilename).send();

or 要么

res.download(zipFilename)send();

or pipe the stream with: 或通过以下方式传递流:

const filestream = fs.createReadStream(zipFilename);
filestream.pipe(res);

on my Frontend i try to parse it with: 在我的前端,我尝试解析为:

parseJSON(response) => {
  return response.clone().json().catch(() => response.text());
}

everything i tried ends up with an empty zip file. 我尝试的所有内容都以一个空的zip文件结尾。 Any suggestions? 有什么建议么?

There are various issues with the options that you tried out: 您尝试的选项存在各种问题:

  • res.attachment will just set the Content-Type and Content-Disposition headers, but it will not actually send anything. res.attachment只会设置Content-TypeContent-Disposition标头,但实际上不会发送任何内容。

    You can use this to set the headers properly, but you need to pipe the ZIP file into the response as well. 您可以使用它来正确设置标题,但是您也需要将ZIP文件通过管道传递到响应中。

  • res.sendfile : You should not call .send() after this. res.sendfile.send()不应调用.send() From the official docs' examples: 从官方文档的示例:

     app.get('/file/:name', function (req, res, next) { var options = { ... }; res.sendFile(req.params.name, options, function (err) { if (err) { next(err); } else { console.log('Sent:', fileName); } }); }); 

    If the ZIP is properly built, this should work fine and set the proper Content-Type header as long as the file has the proper extension. 如果正确构建了ZIP,则只要文件具有适当的扩展名,它就可以正常工作并设置适当的Content-Type标头。

  • res.download : Same thing, you should not call .send() after this. res.download :同样,您不应在此之后调用.send() From the official docs' examples: 从官方文档的示例:

     res.download('/report-12345.pdf', 'report.pdf', function(err) { ... }); 

    res.download will use res.sendfile to send the file as an attachment, thus setting both Content-Type and Content-Disposition headers. res.download将使用res.sendfile作为附件发送文件,从而设置Content-TypeContent-Disposition标头。

However, you mention that the ZIP file is being sent but it is empty, so you should probably check if you are creating the ZIP file properly. 但是,您提到正在发送ZIP文件,但该文件为空,因此您可能应该检查是否正确创建了ZIP文件。 As long as they are built properly and the extension is .zip , res.download should work fine. 只要它们正确构建且扩展名为.zipres.download应该可以正常工作。

If you are building them on the fly, check this out: 如果要动态构建它们,请检查以下内容:

This middleware will create a ZIP file with multiples files on the fly and send it as an attachment. 该中间件将动态创建一个包含多个文件的ZIP文件,并将其作为附件发送。 It uses lazystream and archiver 它使用lazystreamarchiver

const lazystream = require('lazystream');
const archiver = require('archiver');


function middleware(req, res) { 
    // Set the response's headers:
    // You can also use res.attachment(...) here.

    res.writeHead(200, {
        'Content-Type': 'application/zip',
        'Content-Disposition': 'attachment; filename=DOWNLOAD_NAME.zip',
    });

    // Files to add in the ZIP:

    const filesToZip = [
        'assets/file1',
        'assets/file2',
    ];

    // Create a new ZIP file:

    const zip = archiver('zip');

    // Set up some callbacks:

    zip.on('error', errorHandler);

    zip.on('finish', function() {
        res.end(); // Send the response once ZIP is finished.
    });

    // Pipe the ZIP output to res:  

    zip.pipe(res);

    // Add files to ZIP:

    filesToZip.map((filename) => {
        zip.append(new lazystream.Readable(() => fs
            .createReadStream(filename), {
               name: filename,
            });
    });

    // Finalize the ZIP. Compression will start and output will
    // be piped to res. Once ZIP is finished, res.end() will be 
    // called.

    zip.finalize();
}

You can build around this to cache the built ZIPs instead of building them on the fly every time, which is time and resource consuming and totally unadvisable for most uses cases. 您可以围绕它进行构建,以缓存已构建的ZIP,而不是每次都在运行中即时构建它们,这既浪费时间和资源,对于大多数用例来说也不可取。

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

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