【问题标题】:Node.js Can't set headers after they are sent. When initiating an XHR request within another XHR requestNode.js 发送后无法设置标头。在另一个 XHR 请求中启动 XHR 请求时
【发布时间】:2012-03-09 02:46:08
【问题描述】:

Node.js 无法处理执行类似于以下 jQuery/Zepto XHR 模式的客户端代码:

$.ajax({
  type: 'POST',
  url: '/someUrl',
  success: function(response) {
     $.ajax({  // ... do another XHR

我之前在其他框架中做过这个(在另一个 XHR 请求中启动 XHR 请求)模式。我已经阅读了Node.js Error: Can't set headers after they are sent 以及 Node.js 服务器的基于事件的模型是如何工作的。换句话说,第一个 XHR 请求没有调用 res.end() 所以当第二个 XHR 请求被调用时 Node.js 抱怨(在一个连续的循环中)。

我的问题是:谁能推荐一种替代模式来链接 XHR 请求客户端?我可以在 Node.js 服务器端做些什么来保持现有的客户端模式吗?

根据接受的答案更新
错误肯定在我自己的服务器端代码中。一个简单的验证函数抛出了一个错误,但在捕获它时,只调用了 res.end()。由于某种原因,我调用 res.end() 的假设会立即停止函数的执行。在这种情况下,在将 JSON 消息发送到客户端后,插入“return”会立即停止执行。

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. 

【问题讨论】:

  • 再想一想,另一种模式(当然更有效)是如果第二个 XHR 请求是发送到 SAME 服务器的,那么打开第二个连接是浪费的,因为一个已经打开了。因此,与其考虑对后端 api 进行多次单独调用(比如一个调用 getUsers,另一个调用 getProfiles),不如将不同的数据合并到一个 XHR 请求中(比如 getPage?modules=getUsers,getProfiles)。想法?
  • 老实说,我认为我们需要查看 Node.js 中的后端代码以了解发生了什么,@exshovelrydr。您描述的模式当然应该在 Node.js 中工作,如果我没看错的话——一旦服务器传输了所有数据,就会调用 success 回调,因此 Node response 对象应该已经关闭以达到该点,并且第二次 AJAX 调用不应该产生影响。

标签: jquery node.js xmlhttprequest zepto


【解决方案1】:

问题不是你想的那样。由于回调,您的两个 XHR 是串行发生的,而不是并行发生的。第一个请求的success 回调在第一个请求的整个请求/响应过程完成之前不会触发(node.js 已经调用了 response.end() 并且浏览器已经接收并解析了响应)。只有这样,第二个 XHR 才会开始。您拥有的客户端 AJAX 模式很好。它同样适用于 node.js 和任何其他 Web 服务器。

您的问题出在服务器端 node.js 代码中,但这不是 node 中的错误或限制,而是您的编程错误。发布您的服务器端代码,我们可以帮助您追踪它。对于 node.js 初学者来说,通过一个简单的编码错误遇到这个错误是很常见的。

【讨论】:

  • 感谢您的解释。我做了一个简单的测试,将 XHR 请求链接到 Node.js 后端,它按预期工作。我将调试我的代码,看看是否能找到错误。
猜你喜欢
  • 2013-04-01
  • 2014-07-29
  • 2015-01-05
  • 1970-01-01
  • 2020-05-14
  • 2016-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多