Node.js 发送后无法设置标头。当在另一个 XHR 请求中发起一个 XHR 请求时
Node.js 无法处理我的客户端代码,该代码执行类似于下面的 jQuery/Zepto XHR 模式的操作:
$.ajax({
type: 'POST',
url: '/someUrl',
success: function(response) {
$.ajax({ // ... do another XHR
我之前在其他框架中已经完成了这种(在另一个 XHR 请求中发起 XHR 请求)模式。我读过有关 Node.js 错误:可以'发送后设置标头以及 Node.js 服务器的基于事件的模型如何工作。换句话说,第一个 XHR 请求尚未调用 res.end(),因此当调用第二个 XHR 请求时,Node.js 会抱怨(顺便说一句,在连续循环中)。
我的问题是:是否有人能够推荐一种替代模式来链接客户端 XHR 请求?我可以在 Node.js 服务器端做一些事情来保持现有的客户端模式吗?
根据接受的答案进行更新
这个错误肯定是在我自己的服务器端代码中。一个简单的验证函数抛出错误,但在捕获错误后,仅调用 res.end() 。由于某种原因,我假设调用 res.end() 会立即停止函数的执行。在这种情况下,插入“返回”会在将 JSON 消息发送到客户端后立即停止执行。
if (_.isEmpty(req.body)) {
res.end(JSON.stringify({'Error':'POST required'}));
// suppose 'return' is needed here as well
return
} else {
try {
if (_.has(req.body, 'id')) {
id = parseInt(req.body['id']);
} else {
throw {'Error':'Missing param in req.body'};
} // end if
} catch(err) {
res.end(JSON.stringify({'Error':'Missing key(s)','Keys':_.keys(req.body)}));
// without a return here, the code below this 'do some more work' would
// be executed
return
} // end else
// do some more work
// without the above 'return''s the code would
// a) make a database call
// b) call res.end() again!!! <-- bad.
Node.js can't handle my client code that performs something similar to jQuery/Zepto XHR pattern below:
$.ajax({
type: 'POST',
url: '/someUrl',
success: function(response) {
$.ajax({ // ... do another XHR
I've done this (initiating an XHR request within another XHR request) pattern before within other frameworks. I've read about Node.js Error: Can't set headers after they are sent and how the event-based model of Node.js server works. In other words, the first XHR request hasn't called res.end() so when the second XHR request is called Node.js complains (in a continuous loop btw).
My questions are: Would anyone be able to recommend an alternative pattern to chaining XHR requests client-side? Is there something I can do Node.js server-side to keep the existing client-side pattern?
Update Based On Accepted Answer
The mistake is certainly in my own server side code. A simple validation function was throwing an error but upon catching it, only res.end() was called. For some reason the assumption I had was calling res.end() would immediately stop the execution of the function. In this case, inserting a 'return' stops execution immediately after sending the JSON message to the client.
if (_.isEmpty(req.body)) {
res.end(JSON.stringify({'Error':'POST required'}));
// suppose 'return' is needed here as well
return
} else {
try {
if (_.has(req.body, 'id')) {
id = parseInt(req.body['id']);
} else {
throw {'Error':'Missing param in req.body'};
} // end if
} catch(err) {
res.end(JSON.stringify({'Error':'Missing key(s)','Keys':_.keys(req.body)}));
// without a return here, the code below this 'do some more work' would
// be executed
return
} // end else
// do some more work
// without the above 'return''s the code would
// a) make a database call
// b) call res.end() again!!! <-- bad.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题不是你想的那样。由于回调,您的两个 XHR 是串行发生的,而不是并行发生的。第一个请求的
success
回调不会触发,直到第一个请求的整个请求/响应过程完成(node.js 已经调用了 response.end() 并且浏览器已接收并解析的回应)。然后第二个 XHR 才会开始。您拥有的客户端 AJAX 模式很好。它将同样适用于 Node.js 和任何其他 Web 服务器。您的问题出在您的服务器端 node.js 代码中,但这不是节点中的错误或限制,而是您的编程错误。发布您的服务器端代码,我们可以帮助您追踪它。对于 Node.js 初学者来说,由于简单的编码错误而遇到此错误是很常见的。
The problem is not what you think it is. Your two XHRs happen in serial, not parallel, due to the callbacks. The
success
callback of the first one won't fire until the entire request/response process is complete for the first request (node.js has already called response.end() and the browser has received and parsed the response). Only then does the second XHR commence. The client side AJAX pattern you have is fine. It will work with node.js and any other web server equally well.Your problem is in your server side node.js code, but it's not a bug or limitation in node, it's a programming mistake on your part. Post your server side code and we can help you track it down. It is very common for node.js beginners to hit this error with a simple coding mistaking.