Express.js - How to check if headers have already been sent?
Asked Answered
P

3

100

I am writing a library which may set headers. I want to give a custom error message if headers have already been sent, instead of just letting it fail with the "Can't set headers after they are sent" message given by Node.js. So how to check if headers have already been sent?

Pyre answered 19/8, 2012 at 21:19 Comment(1)
powerboy would you be able to accept the other answer, because the currently accepted answer doesn't work anymore? See @fiatjaf 's comment.Notepaper
R
75

EDIT: as of express 4.x, you need to use res.headersSent. Note also that you may want to use setTimeout before checking, as it isn't set to true immediately following a call to res.send(). Source

Simple: Connect's Response class provides a public property "headerSent".

res.headerSent is a boolean value that indicates whether the headers have already been sent to the client.

From the source code:

/**
   * Provide a public "header sent" flag
   * until node does.
   *
   * @return {Boolean}
   * @api public
   */

  res.__defineGetter__('headerSent', function(){
    return this._header;
  });

https://github.com/senchalabs/connect/blob/master/lib/patch.js#L22

Rockrose answered 19/8, 2012 at 22:20 Comment(10)
Note that this is not the same as nodejs.org/docs/latest/api/http.html#http_response_headerssent In express it seems to return the headers sent.. rather than a bool of if the headers have been sent.Luik
Everyday I admire how is nodejs easy concept.Acerbate
@Pyre Node currently supports res.headersSent natively, so it's probably a good idea to to start using that property.Notepaper
As of May 17, 2014, res.headerSent has been deprecated by senchalabs/connect in favour of res.headersSent.Ecdysis
it's headersSentnot headerSentBirkenhead
I've edited the answer to reflect the headersSent thing, as it is accepted but is now misleading.Apostatize
@Apostatize setTimeout of how much?Grajeda
Seems it doesn't work to just use zero... I have mine set to 250ms to be safe, but fewer would probably be fine.Apostatize
i flagged this answer for moderation. res.headersSent answer should be the accepted solution as this one no longer works.Favrot
Where is this documented that headersSent is set asynchronously?Pageantry
N
224

Node supports the res.headersSent these days, so you could/should use that. It is a read-only boolean indicating whether the headers have already been sent.

if(res.headersSent) { ... }

See http://nodejs.org/api/http.html#http_response_headerssent

Note: this is the preferred way of doing it, compared to the older Connect 'headerSent' property that Niko mentions.

Notepaper answered 6/6, 2014 at 8:46 Comment(1)
This should be made the accepted answer seeing as the current accepted answer no longer works.Diacetylmorphine
R
75

EDIT: as of express 4.x, you need to use res.headersSent. Note also that you may want to use setTimeout before checking, as it isn't set to true immediately following a call to res.send(). Source

Simple: Connect's Response class provides a public property "headerSent".

res.headerSent is a boolean value that indicates whether the headers have already been sent to the client.

From the source code:

/**
   * Provide a public "header sent" flag
   * until node does.
   *
   * @return {Boolean}
   * @api public
   */

  res.__defineGetter__('headerSent', function(){
    return this._header;
  });

https://github.com/senchalabs/connect/blob/master/lib/patch.js#L22

Rockrose answered 19/8, 2012 at 22:20 Comment(10)
Note that this is not the same as nodejs.org/docs/latest/api/http.html#http_response_headerssent In express it seems to return the headers sent.. rather than a bool of if the headers have been sent.Luik
Everyday I admire how is nodejs easy concept.Acerbate
@Pyre Node currently supports res.headersSent natively, so it's probably a good idea to to start using that property.Notepaper
As of May 17, 2014, res.headerSent has been deprecated by senchalabs/connect in favour of res.headersSent.Ecdysis
it's headersSentnot headerSentBirkenhead
I've edited the answer to reflect the headersSent thing, as it is accepted but is now misleading.Apostatize
@Apostatize setTimeout of how much?Grajeda
Seems it doesn't work to just use zero... I have mine set to 250ms to be safe, but fewer would probably be fine.Apostatize
i flagged this answer for moderation. res.headersSent answer should be the accepted solution as this one no longer works.Favrot
Where is this documented that headersSent is set asynchronously?Pageantry
G
17

Others answers point to Node.js or Github websites.

Below is from Expressjs website: https://expressjs.com/en/api.html#res.headersSent

app.get('/', function (req, res) {
  console.log(res.headersSent); // false
  res.send('OK');
  console.log(res.headersSent); // true
});
Grays answered 13/8, 2018 at 5:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.