【问题标题】:JSON Zip Response in node.jsnode.js 中的 JSON Zip 响应
【发布时间】:2012-09-25 22:12:46
【问题描述】:

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

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

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

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

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

  • adm-zip
  • 节点压缩
  • 压缩流

我取得的最好结果是使用 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 文件,但内容不可读。

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

有什么建议吗?

提前感谢

【问题讨论】:

    标签: json node.js zip express


    【解决方案1】:

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

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

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

    【讨论】:

    • 我应该把 express.compress() 中间件放在哪里?在路由和静态内容之前还是之后?
    • 我相信所有的 app.use() 函数都应该放在路由之前。
    【解决方案2】:

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

    $ npm install compression
    

    然后使用库:

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

    您可以调整很多选项,see here for the list

    【讨论】:

      【解决方案3】:

      我想你的意思是我如何使用节点发送 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);
      

      【讨论】:

      • 嗨,赛义德,感谢您的回答。问题是我们使用的移动解决方案(Titanium SDK)不支持 gzip 文件。
      猜你喜欢
      • 2015-04-30
      • 2014-09-07
      • 1970-01-01
      • 2023-03-04
      • 2020-10-15
      • 1970-01-01
      • 1970-01-01
      • 2018-12-03
      • 1970-01-01
      相关资源
      最近更新 更多