【发布时间】: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回调,因此 Noderesponse对象应该已经关闭以达到该点,并且第二次 AJAX 调用不应该产生影响。
标签: jquery node.js xmlhttprequest zepto