7

我对 node.js 很陌生,我正在尝试发回一个包含 JSON 结果的 zip 文件。我一直在试图弄清楚如何做到这一点,但没有得到预期的结果。

我正在使用 NodeJS、ExpressJS、LocomotiveJS、Mongoose 和 MongoDB。

由于我们正在构建一个面向移动的应用程序,因此我正在尝试尽可能多地节省带宽。

移动应用程序的每日初始加载可能是一个很大的 JSON 文档,因此我想在将其发送到设备之前对其进行压缩。如果可能的话,我想在内存中做所有事情以避免磁盘 I/O。

到目前为止,我尝试了 3 个库:

  • 管理员压缩包
  • 节点压缩
  • 压缩流

我取得的最好结果是使用 node-zip。这是我的代码:

  return Queue.find({'owners': this.param('id')}).select('name extra_info cycle qtype purge purge_time tasks').exec(function (err, docs) {
    if (!err) {
      zip.file('queue.json', docs);
      var data = zip.generate({base64:false,compression:'DEFLATE'});

      res.set('Content-Type', 'application/zip');
      return res.send(data);
    }
    else {
      console.log(err);
      return res.send(err);
    }
  });

结果是下载的 zip 文件,但内容不可读。

我很确定我把事情搞混了,但到目前为止我不知道如何继续。

有什么建议吗?

提前感谢

4

3 回答 3

18

您可以使用以下命令压缩 express 3 中的输出:

app.configure(function(){
  //....
  app.use(express.compress());
});


app.get('/foo', function(req, res, next){
  res.send(json_data);
});

如果用户代理支持 gzip,它会自动为您 gzip。

于 2012-09-25T23:15:59.157 回答
5

对于 Express 4+,compress 不与 Express 捆绑在一起,需要单独安装。

$ npm install compression

然后使用该库:

var compression = require('compression');
app.use(compression());

您可以调整很多选项,请参见此处的列表

于 2017-04-26T14:42:05.880 回答
1

我认为您的意思是如何使用节点发送 Gzip 内容?

Node 0.6 及以上版本有一个内置的zlip模块,所以不需要外部模块。

您可以像这样发送 Gzip 内容。

 response.writeHead(200, { 'content-encoding': 'gzip' });
    json.pipe(zlib.createGzip()).pipe(response);

显然,您需要首先检查客户端是否接受 Gzip 编码,并且还要记住 gzip 是一项昂贵的操作,因此您应该缓存结果。

这是从文档中获取的完整示例

// server example
// Running a gzip operation on every request is quite expensive.
// It would be much more efficient to cache the compressed buffer.
var zlib = require('zlib');
var http = require('http');
var fs = require('fs');
http.createServer(function(request, response) {
  var raw = fs.createReadStream('index.html');
  var acceptEncoding = request.headers['accept-encoding'];
  if (!acceptEncoding) {
    acceptEncoding = '';
  }

  // Note: this is not a conformant accept-encoding parser.
  // See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3
  if (acceptEncoding.match(/\bdeflate\b/)) {
    response.writeHead(200, { 'content-encoding': 'deflate' });
    raw.pipe(zlib.createDeflate()).pipe(response);
  } else if (acceptEncoding.match(/\bgzip\b/)) {
    response.writeHead(200, { 'content-encoding': 'gzip' });
    raw.pipe(zlib.createGzip()).pipe(response);
  } else {
    response.writeHead(200, {});
    raw.pipe(response);
  }
}).listen(1337);
于 2012-09-25T22:30:27.463 回答