Adam Zerner
Adam Zerner

Reputation: 19178

How does Express's res.end() work?

The docs don't really say much.

Ends the response process. Inherited from Node's http.ServerResponse.

Use to quickly end the response without any data. If you need to respond with data, instead use methods such as res.send() and res.json().

res.end();
res.status(404).end();
  1. So is anything sent to the client? I sense that the status line and headers are sent, but no body is sent. Why else would they give the example of res.status(404).end().

  2. If you provide an argument to res.end(), will it send the argument you provided along in the response body like Node's response.end()?

Upvotes: 2

Views: 2878

Answers (3)

Danny Sofftie
Danny Sofftie

Reputation: 1051

I just realized when ending a stream with res.end( ) without passing any data doesn't end the stream as expected. This happens in cases where you render a file and send data along with it, you have to explicitly call res.end( JSON.stringify( {data: data} ) ). I don't know if anyone else has encountered a similar situation. Didn't find it in the docs and it took me some time to figure out why rendering took so long with no success.

Upvotes: 0

josh3736
josh3736

Reputation: 144912

If we look at the source, we see that express doesn't actually provide a end() method. That's what the docs’ “Inherited from Node's http.ServerResponse” tells you – express doesn't provide this method; node core's http module does.

So what does http's end() do?

  1. If HTTP response headers have not yet been sent, they are written to the response stream.
  2. If end() is called with a data argument, the data is passed to write().
  3. If it is necessary to send trailers, those are written to the response stream.
  4. Emits the finish event on the response object, which:

    • If the connection uses keep-alive, node starts processing the next HTTP request.
    • Otherwise, the underlying TCP socket is closed.

So to answer your questions:

  1. Is anything sent to the client? It depends. Calling end() will never cause additional payload (entity-body) data to be sent, but depending on what you've done with the response prior to calling end(), more bytes may be written to the underlying socket by node on your behalf.

    Your intuition is correct; res.status(404).end() will cause the server to respond with HTTP 404 headers and a Content-Length of zero (totally empty body).

  2. Yes, data passed to end() is written to the response stream because the end() method is node's. It's important to remember that the request and response objects that express gives you are just regular http.IncomingMessage and http.ServerResponse objects that are augmented with some additional functionality by express in the form of extra methods. All of the methods provided by node core are still available.

Upvotes: 2

Ruben
Ruben

Reputation: 1749

When you send a information back, you must end the stream of information. You do this by calling end(). Sending the status code 404 can still be followed by content, such as a custom 404 page, rather than the browser showing you the default This page can not be found (Old, but an example of Chrome's built-in 404 page). If you do not end the request, the browser will keep waiting for the end of the stream and report a timeout after a certain amount of time.

res.send() automatically closes the request for you, so that you don't have to call end() manually.

Upvotes: 2

Related Questions