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: Can' t устанавливать заголовки после их отправки и как работает основанная на событиях модель сервера 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. 

person exshovelrydr    schedule 17.02.2012    source источник
comment
Размышляя над этим еще немного, альтернативный шаблон (и, по общему признанию, более эффективный): ЕСЛИ второй запрос XHR относится к ОДНОМУ серверу, тогда расточительно открывать второе соединение, поскольку одно уже открыто. Таким образом, вместо того, чтобы думать о том, чтобы делать много отдельных вызовов к серверному API (скажем, один для getUsers, а другой для getProfiles), может быть лучше объединить разрозненные данные в один запрос XHR (скажем, getPage?modules=getUsers,getProfiles). Мысли?   -  person exshovelrydr    schedule 17.02.2012
comment
Честно говоря, я думаю, нам нужно увидеть внутренний код в Node.js, чтобы понять, что происходит, @exshovelrydr. Шаблон, который вы описываете, безусловно, должен работать в Node.js, если я правильно его читаю — обратный вызов success вызывается после того, как все данные были переданы сервером, поэтому объект Node response должен был быть уже закрыт, чтобы достичь этой точки, и второй вызов AJAX не должен иметь влияния.   -  person    schedule 17.02.2012


Ответы (1)


Проблема не в том, что вы думаете. Ваши два XHR происходят последовательно, а не параллельно, из-за обратных вызовов. Обратный вызов success первого не сработает, пока весь процесс запроса/ответа не будет завершен для первого запроса (node.js уже вызвал response.end(), и браузер получил и проанализировал ответ). Только после этого начинается второй XHR. Шаблон AJAX на стороне клиента, который у вас есть, в порядке. Он одинаково хорошо будет работать с node.js и любым другим веб-сервером.

Ваша проблема заключается в вашем коде node.js на стороне сервера, но это не ошибка или ограничение в узле, это ошибка программирования с вашей стороны. Опубликуйте свой код на стороне сервера, и мы поможем вам его отследить. Новички в node.js очень часто сталкиваются с этой ошибкой из-за простой ошибки в коде.

person Peter Lyons    schedule 18.02.2012
comment
Спасибо за объяснение. Я провел простой тест, который связывал запросы XHR с серверной частью Node.js, и он работал, как и ожидалось. Я собираюсь отладить свой код и посмотреть, смогу ли я найти ошибку. - person exshovelrydr; 20.02.2012