res.json没有HTTP状态代码的标题

时间:2019-04-10 07:00:06

标签: node.js json express get http-status-codes

我想让标头伴随我发送过来的json对象。当我尝试setHeaders时,出现Can't set headers after they are sent.错误。

我在此SO post中看到

  

自Express.js 3x起,响应对象具有json()方法,该方法可以设置   正确地为您提供所有标头,并以JSON返回响应   格式。

但是,当我执行res.status(404).json({"error", "message not found"})时,没有标头(http状态)陪伴发送到客户端的json对象。客户看到的是:

{
          "error:": "Message Not Found"
}

Web服务:

var express = require('express');
var bodyParser  = require('body-parser');
var crypto = require('crypto');

var app = express();
var message_dict = [];
app.set('json spaces', 40);

app.use(bodyParser.urlencoded({
  extended: true
}));

app.use(bodyParser.json());
app.use(express.json());

app.post('/messages', function(request, response){
    var string_message = request.body.message;
    var json_obj = request.body
    var hash_key = crypto.createHash('sha256').update(string_message).digest('hex');
    message_dict[hash_key] = json_obj
    var encrypted_data = {'digest' : hash_key};
    response.json(encrypted_data);

});

app.get('/messages/*', function(request, response) {
  var hash_key = request.params[0];

  if(hash_key in message_dict){
    response.json(message_dict[hash_key]);
  }
  else{
    response.status(404).json({'error:' : 'Messag Not Found'})
  }

});



app.listen(8080, function() {
  console.log('Example app listening on port 8080!');
});

2 个答案:

答案 0 :(得分:2)

我认为您混淆了响应头和响应主体,.json()设置了正确的响应头(特别是Content-Type),响应主体仍然只是您传递给调用的参数。

您是否有特定的原因希望响应标题出现在响应正文中?响应标头通常对请求者没有多大用处,并且在从服务器获取响应时可以很容易地访问它们(res.headers属性)。

要真正回答您的问题(不确定为什么要这么做):

var json = {'error:' : 'Messag Not Found'}
response.type('application/json')
response.writeHead(404)
json.headers = response._header; // _header not documented but works
response.end(JSON.stringify(json));

答案 1 :(得分:-1)

第一件事,因为您现在正在发布此问题,所以我假设您使用的是Express 4.x而不是3.x,这是您链接到的SO帖子中引用的Express版本,因此请不要关注该帖子的建议是几年前的。许多功能的操作从版本3更改为版本4,因此有关特定功能行为的许多答案可能已过时。可以在here中找到Express 4文档。

我认为您可能会将app.set()函数与res.set()函数混淆。 app.set()函数为您的应用程序设置应用程序设置,而不是响应对象上的标头值。有关如何使用app.set()函数的更多信息,请参见here

如果要在响应对象上设置各个标头值,则需要使用res.set()函数。 res.set()函数的文档可以在here中找到。您可以使用此函数设置单个或多个标题值,具体取决于传递给函数的参数。您可以在各个路由定义的回调函数中调用此函数。

要解决上述最初的问题,res.status() function只需将响应对象上的res.statusCode属性设置为您指定的任何值,而res.json() {{ 3}}将响应对象的主体设置为您指定的JSON对象。简而言之,在您未明确告知响应对象的情况下,这些函数或任何其他Express函数都不会自动将值添加到响应对象。