【问题标题】:How to return a complex JSON response with Node.js?如何使用 Node.js 返回复杂的 JSON 响应?
【发布时间】:2012-02-12 21:43:54
【问题描述】:

使用 nodejs 和 express,我想使用 JSON 返回一个或多个对象(数组)。在下面的代码中,我一次输出一个 JSON 对象。它有效,但这不是我想要的。产生的响应不是有效的 JSON 响应,因为我有很多对象。

我很清楚我可以简单地将所有对象添加到一个数组中并在 res.end 中返回该特定数组。但是,我担心这可能会变得繁重,处理和内存密集。

使用 nodejs 实现这一目标的正确方法是什么? query.each 是正确的调用方法吗?

app.get('/users/:email/messages/unread', function(req, res, next) {
    var query = MessageInfo
        .find({ $and: [ { 'email': req.params.email }, { 'hasBeenRead': false } ] });

    res.writeHead(200, { 'Content-Type': 'application/json' });   
    query.each(function(err, msg) {
        if (msg) { 
            res.write(JSON.stringify({ msgId: msg.fileName }));
        } else {
            res.end();
        }
    });
});

【问题讨论】:

    标签: json node.js express mongoose


    【解决方案1】:

    在 express 3 上你可以直接使用 res.json({foo:bar})

    res.json({ msgId: msg.fileName })
    

    documentation

    【讨论】:

    • 没有快递怎么办?
    • @Ludwik11 res.write(JSON.stringify(foo))。如果foo 很大,您可能需要将其切碎(字符串化,然后一次写入块)。可能还想查看您的标题"Content-Type":"application/json" 或类似的适当。
    【解决方案2】:

    我不知道这是否真的有什么不同,但您可以执行以下操作,而不是遍历查询光标:

    query.exec(function (err, results){
      if (err) res.writeHead(500, err.message)
      else if (!results.length) res.writeHead(404);
      else {
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.write(JSON.stringify(results.map(function (msg){ return {msgId: msg.fileName}; })));
      }
      res.end();
    });
    

    【讨论】:

      【解决方案3】:

      [编辑] 在查看了 Mongoose 文档后,您似乎可以将每个查询结果作为单独的块发送; Web 服务器使用 chunked transfer encoding by default,因此您只需将数组包裹在项目周围,使其成为有效的 JSON 对象。

      大致(未经测试):

      app.get('/users/:email/messages/unread', function(req, res, next) {
        var firstItem=true, query=MessageInfo.find(/*...*/);
        res.writeHead(200, {'Content-Type': 'application/json'});
        query.each(function(docs) {
          // Start the JSON array or separate the next element.
          res.write(firstItem ? (firstItem=false,'[') : ',');
          res.write(JSON.stringify({ msgId: msg.fileName }));
        });
        res.end(']'); // End the JSON array and response.
      });
      

      或者,正如您所提到的,您可以简单地按原样发送数组内容。在这种情况下the response body will be buffered 并立即发送,这可能会为大型结果集消耗大量额外内存(超出存储结果本身所需的内存)。例如:

      // ...
      var query = MessageInfo.find(/*...*/);
      res.writeHead(200, {'Content-Type': 'application/json'});
      res.end(JSON.stringify(query.map(function(x){ return x.fileName })));
      

      【讨论】:

      • 这是个好主意。但是对我来说它看起来有点hacky。我希望 nodejs 能提供一些更优雅的东西。
      猜你喜欢
      • 2015-12-26
      • 1970-01-01
      • 2013-08-22
      • 2012-01-16
      • 1970-01-01
      • 2015-12-27
      • 2012-03-08
      • 2014-03-10
      • 2018-12-24
      相关资源
      最近更新 更多