简体   繁体   English

使用Express和node-archiver即时生成zip存档

[英]Generating zip archive on-the-fly using Express and node-archiver

I'm trying to generate a zip archive of icons on-the-fly and stream the response to the user to download, via a JSON POST request. 我正在尝试即时生成图标的zip存档,并通过JSON POST请求将响应流式传输给用户以进行下载。

The zip itself is created and the response is returned, but the client-side is not prompted to download the file, and the response is garbled (which I assume is the contents of the archive). 将创建zip本身并返回响应,但是不会提示客户端下载文件,并且响应会出现乱码(我认为这是存档的内容)。

app.post('/download', function(request, response) {

  var icons = request.body;
  var filename = 'icons.zip';

  response.attachment(filename);

  var zip = Archiver('zip');

  zip.on('finish', function(error) {
    return response.end();
  });

  zip.pipe(response);

  for (var i = 0; i < icons.length; i++) {

    var icon = getIcon(icons[i]);
    zip.append(fs.createReadStream('public/' + icon.svg), { name: icon.title + '.svg' });
  }

  zip.finalize();
});

I'm wondering if there's anything missing from the server-side code that's preventing the download on the client-side, but from the example I've followed ( https://github.com/archiverjs/node-archiver/blob/master/examples/express.js ), it doesn't seem to be the case. 我想知道服务器端代码中是否缺少阻止客户端下载的内容,但是从我遵循的示例中可以看出( https://github.com/archiverjs/node-archiver/blob/master /examples/express.js ),似乎并非如此。

Here's some screenshots of the request made and the response received: 以下是发出的请求和收到的响应的屏幕截图:

请求和响应头

响应

AJAX calls don't trigger file downloads in a browser, so you need to work around that. AJAX调用不会触发浏览器中的文件下载,因此您需要解决此问题。

One possibility is to change the request from a POST to a GET and put the names of the icons in the URL as parameters. 一种可能是将请求从POST更改为GET ,并将图标的名称放在URL中作为参数。

Your Express route would look like this: 您的Express路线如下所示:

app.get('/download/*?', function(request, response) {
  // Make sure icons names were provided:
  if (! request.params[0]) {
    return response.sendStatus(400);
  }

  // Split on `/`, which is used as separator between icon names:
  var icons = request.params[0].split(/\//);

  // The rest can be the same
  ...
});

Client-side, you would use this: 客户端,您将使用以下代码:

location.href = 'http://your-server/download/Chevron%20Down/Close/Trash';

(obviously you can also generate that URL dynamically based on user input, as long as you make sure that the icon names are properly URL-encoded) (显然,只要确保图标名称正确地进行了URL编码,您还可以根据用户输入动态生成该URL)

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

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