0

I would like to have headers accompany the json object that I send over. When I try to setHeaders, I get a Can't set headers after they are sent. error.

I see in this SO post that

Since Express.js 3x the response object has a json() method which sets all the headers correctly for you and returns the response in JSON format.

However, when I do res.status(404).json({"error", "message not found"}) no headers (the http status)accompany the json object that gets sent to the client. All the client sees is:

{
          "error:": "Message Not Found"
}

Web service:

var express = require('express');
var bodyParser  = require('body-parser');
var crypto = require('crypto');

var app = express();
var message_dict = [];
app.set('json spaces', 40);

app.use(bodyParser.urlencoded({
  extended: true
}));

app.use(bodyParser.json());
app.use(express.json());

app.post('/messages', function(request, response){
    var string_message = request.body.message;
    var json_obj = request.body
    var hash_key = crypto.createHash('sha256').update(string_message).digest('hex');
    message_dict[hash_key] = json_obj
    var encrypted_data = {'digest' : hash_key};
    response.json(encrypted_data);

});

app.get('/messages/*', function(request, response) {
  var hash_key = request.params[0];

  if(hash_key in message_dict){
    response.json(message_dict[hash_key]);
  }
  else{
    response.status(404).json({'error:' : 'Messag Not Found'})
  }

});



app.listen(8080, function() {
  console.log('Example app listening on port 8080!');
});
maddie
  • 1,854
  • 4
  • 30
  • 66

2 Answers2

2

I think you're confusing response headers and response body, .json() sets the correct response headers (specifically Content-Type), the response body is still only the param you pass into the call.

Is there a specific reason you want the response headers to appear in the response body? response headers are usually of very little use to the requester and can be easily accessed by when getting the response from the server (res.headers property).

To actually answer your question (not sure why you would do that):

var json = {'error:' : 'Messag Not Found'}
response.type('application/json')
response.writeHead(404)
json.headers = response._header; // _header not documented but works
response.end(JSON.stringify(json));
Shachar
  • 359
  • 2
  • 6
0

First thing, since you are posting this question now, I am assuming that you are using Express 4.x instead of 3.x, which is the Express version referenced in that SO post you linked to, so don't follow the advice of that post which is from a few years ago. The operation of a lot of functionality changed from version 3 to version 4, so many answers about behavior of specific functions may be out-of-date. Express 4 documentation can be found here.

I think that you may be confusing the app.set() function for the res.set() function. The app.set() function set application settings for your application, not header values on a response object. See here for more information on how to use the app.set() function.

If you want to set individual header values on a response object, you need to use the res.set() function. Documentation for the res.set() function can be found here. You can set individual or multiple header values using this function depending on what parameters you pass to the function. You would call this function in the callback function of your individual route definition.

And to address your initial issue above, the res.status() function simply sets the res.statusCode property on the response object to whatever value you specify, while the res.json() function sets the body of the response object to the JSON object that you specify. In short, none of these or any other Express functions automatically add values to a response object without you explicitly telling it to do so.

Keith Dawson
  • 1,475
  • 16
  • 27