Solved -Why can’t we do multiple response.send in Express.js?

79👍

Perhaps you are looking for a solution using response.write.

response.write("foo");
response.write("bar");
//...
response.end()

res.send implicitly incorporates res.write followed by res.end. While calling res.send multiple times will work for the first call, subsequent calls will not have any effect. This is because the first res.send call concludes the response and prevents further additions to it.

21👍

response.send is used to send an entire HTTP response to the client, including headers and content. This is why you cannot call it multiple times. In fact, it ends the response, so you don’t need to explicitly call response.end when using response.send.

It seems that you are trying to use send as a buffer by writing to it with the intention to flush later. However, this is not the intended use of the method. Instead, you should build up your response in your code and then make a single send call.

Unfortunately, I am unable to provide information on the specific reasons or timing behind this change, but this behavior has been consistent since at least Express 3.

1👍

res.write immediately sends bytes to the client

To clarify the functionality of res.write, it should be noted that it does not accumulate the response and wait for res.end(). Instead, it promptly sends the data to the client.

This implies that upon its first invocation, res.write transmits the necessary HTTP reply headers, including the status, to ensure a meaningful response. Therefore, if you intend to set a custom status or header, it must be done before the initial call to res.write, similar to how it is accomplished with send().

Please be aware that using write() is not typically recommended in a simple web application. Sending the reply gradually to the browser adds complexity to the process, so it should only be utilized if absolutely necessary.

Use res.locals to build the response across middleware

This was my initial use case, and res.locals fits perfectly for this purpose. I can easily store data in an Array within res.locals, and then in the very last middleware, concatenate the contents and perform a final send to transmit everything at once. For example:

async (err, req, res, next) => {
  res.locals.msg = ['Custom handler'];
  next(err);
},
async (err, req, res, next) => {
  res.locals.msg.push('Custom handler 2');
  res.status(500).send(res.locals.msg.join('\n'));
}
  

Leave a comment