Node.js Can't set headers after they are sent. When initiating an XHR request within another XHR request

StackOverflow https://stackoverflow.com/questions/9332698

Question

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. 
Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top