我正在使用Node.js.
我有一段代码可以很好地返回预期的响应并快速收到响应:
if (req.accepts('json')) {
res.header('Content-Type', 'application/json');
res.send(res.locals.items, 200);
}
除了状态200,我想在标题中添加一条消息。因此,我稍微修改了一下代码:
if (req.accepts('json')) {
res.writeHead( 200, 'my_customizd_message', {'Content-Type' : 'application/json'} );
res.send(res.locals.items);
}
然后,它抱怨"错误:在发送标题后不能设置标题"。
我尝试了别的东西:
if (req.accepts('json')) {
res.writeHead( 200, 'my_customizd_message', {'Content-Type' : 'application/json'} );
res.end();
}
控制台上没有错误消息。但是,没有任何回报。代码永远在运行。我希望有人可以帮助我。非常感谢你。
答案 0 :(得分:2)
看起来你正在使用Express。重要的是要了解writeHead
由节点的核心HTTP库提供,而Express通常会为您管理标头。换句话说,您不应该在Express应用程序中调用writeHead
。
第一次尝试时出现的错误来自Expess在您拨打writeHead
(Express提供的方法)时调用send
这一事实。因为您已经手动将标题写入线路,所以Express尝试编写标头失败并引发异常。
你的第二次尝试什么也没有返回,因为你写了标题,然后立即结束响应而不发送任何数据 - 没有错误,因为你没有调用Express方法,但当然客户端什么都看不到。
你遇到的问题是Express的响应方法(如send
)设置了各种标题(在某些情况下甚至是响应代码),然后依靠节点的implicit header function来实际编写标题。请注意,writeHead
永远不会出现在Express的源代码中。
当您(或在此情况下代表您的Express)开始将数据写入响应(write
或end
),节点checks以查看是否已发送标头。如果没有,它会为您调用writeHead
,merges任何标头直接传递给该函数,并且标头存储在res._headers
中(您通过调用res.setHeader
修改的私有属性)。
如果很难完成自定义HTTP状态消息,有几件事情会结合起来:
快速方法(如send
)一次设置标题,写入数据和end
响应。因此,您无法修改标头或自行使用自定义状态消息致电writeHead
。
当(当前版本的)节点的HTTP模块写入隐式标头时,它总是写入默认状态消息。没有记录的自定义方式。
那么如何获得自定义状态消息?
您可以绕过Express的逻辑并手动响应请求(就像您第二次尝试一样)。但是,当您执行此操作时,您会错过很多有用的功能。只有在你完全知道自己在做什么的情况下才这样做。 (所以不要)
最简单的答案是节点的0.11分支adds res.statusMessage
,这样您就可以在调用res.send
之前简单地设置所需的消息。不幸的是,0.11不稳定,不应该用于生产。 0.12(具有此功能的下一个稳定版本)将很快出现。当然,这个版本还有几个重大变化(特别是在C ++模块方面),所以你可能无法立即使用它。
节点0.10的权宜之计答案是猴子补丁http.ServerResponse.prototype._implicitHeader
。这是一个可能破坏事情的肮脏黑客。自行承担风险。
http.ServerResponse.prototype._implicitHeader = function() {
this.writeHead(this.statusCode, this.statusMessage);
};
当您的应用启动时执行此操作一次。这样您就可以在调用res.statusMessage = 'My Custom Status';
之前设置res.send
,就像在0.11中一样。
答案 1 :(得分:0)
我以前没用过它,但是这个怎么样?:
if (req.accepts('json')) {
res.writeHead( 200, {
'Content-Type' : 'application/json',
'my_customizd_message':'blah blah'
});
res.send(res.locals.items);
}
答案 2 :(得分:0)
现在,我添加了另一行:
res.header('warning' : 'my_customized_message');
它有效。
答案 3 :(得分:0)
根据我刚刚阅读的内容,您可以使用:
res.setHeader(name, value);
setHeader()
适用于两个条件:
writeHead()
(即如果已经发送标题,则无法设置标题)res.write()
或res.end 如果您需要阅读更多内容,我只是从“ professional node.js ”一书中提取了这些信息,第11页第99页