410

I'm sending the following JSON string to my server.

(
        {
        id = 1;
        name = foo;
    },
        {
        id = 2;
        name = bar;
    }
)

On the server I have this.

app.post('/', function(request, response) {

    console.log("Got response: " + response.statusCode);

    response.on('data', function(chunk) {
        queryResponse+=chunk;
        console.log('data');
    });

    response.on('end', function(){
        console.log('end');
    });
});

When I send the string, it shows that I got a 200 response, but those other two methods never run. Why is that?

Mridang Agarwalla
  • 43,201
  • 71
  • 221
  • 382
neuromancer
  • 53,769
  • 78
  • 166
  • 223

8 Answers8

709

I think you're conflating the use of the response object with that of the request.

The response object is for sending the HTTP response back to the calling client, whereas you are wanting to access the body of the request. See this answer which provides some guidance.

If you are using valid JSON and are POSTing it with Content-Type: application/json, then you can use the bodyParser middleware to parse the request body and place the result in request.body of your route.

Update for Express 4.16+

Starting with release 4.16.0, a new express.json() middleware is available.

var express = require('express');

var app = express();

app.use(express.json());

app.post('/', function(request, response){
  console.log(request.body);      // your JSON
   response.send(request.body);    // echo the result back
});

app.listen(3000);

Updated for Express 4.0 - 4.15

Body parser was split out into its own npm package after v4, requires a separate install npm install body-parser

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

var app = express();

app.use(bodyParser.json());

app.post('/', function(request, response){
  console.log(request.body);      // your JSON
   response.send(request.body);    // echo the result back
});

app.listen(3000);

For earlier versions of Express (< 4)

var express = require('express')
  , app = express.createServer();

app.use(express.bodyParser());

app.post('/', function(request, response){
  console.log(request.body);      // your JSON
  response.send(request.body);    // echo the result back
});

app.listen(3000);

Test along the lines of:

$ curl -d '{"MyKey":"My Value"}' -H "Content-Type: application/json" http://127.0.0.1:3000/
{"MyKey":"My Value"}
danronmoon
  • 3,814
  • 5
  • 34
  • 56
Pero P.
  • 25,813
  • 9
  • 61
  • 85
226

For Express v4+

install body-parser from the npm.

$ npm install body-parser

https://www.npmjs.org/package/body-parser#installation

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

var app = express()

// parse application/json
app.use(bodyParser.json())

app.use(function (req, res, next) {
  console.log(req.body) // populated!
  next()
})
chrisarton
  • 4,401
  • 2
  • 18
  • 15
  • 31
    why do they keep taking out stuff everyone uses? – light24bulbs Oct 17 '14 at 04:30
  • 13
    @light24bulbs So it (Express) will be more lean and mean for those who don't use/need that. – andyengle Nov 04 '14 at 02:38
  • 6
    @andyengle That does make sense. But I think virtually everyone uses request parsing. That seems like a core feature to me. – light24bulbs Nov 05 '14 at 02:54
  • 27
    Since the middleware function interface is a standard used by many libraries, it also allows apps that don't use Express to use these middleware functions. – Anm Jan 31 '15 at 12:53
  • 3
    Taking it out of express doesn't allow it to be used by apps that do not use requests. They could have made it separate, and included it in express by default. – J.J Oct 23 '16 at 14:31
  • 2
    my body returns empty when data type is JSON – mrid Oct 04 '17 at 06:25
  • it works; is this line `app.use(bodyParser.json());` always needed to run before importing routes `app.use('/', require('./routes'));`? – Ridhwaan Shakeel Jul 21 '21 at 21:35
59

For those getting an empty object in req.body

I had forgotten to set headers: {"Content-Type": "application/json"} in the request. Changing it solved the problem.

Daniel Thompson
  • 2,193
  • 4
  • 23
  • 37
  • 2
    wow, thanks! life saver! easy to forget when invoking a lambda directly on the command line! `serverless invoke local -f app -l -d '{ "path": "/conferences", "httpMethod": "POST", "body": { "conference_name": "test" }, "headers": {"Content-Type": "application/json"} }'` – Andrew Oct 26 '20 at 07:04
27

@Daniel Thompson mentions that he had forgotten to add {"Content-Type": "application/json"} in the request. He was able to change the request, however, changing requests is not always possible (we are working on the server here).

In my case I needed to force content-type: text/plain to be parsed as json.

If you cannot change the content-type of the request, try using the following code:

app.use(express.json({type: '*/*'}));

Instead of using express.json() globally, I prefer to apply it only where needed, for instance in a POST request:

app.post('/mypost', express.json({type: '*/*'}), (req, res) => {
  // echo json
  res.json(req.body);
});
anneb
  • 5,510
  • 2
  • 26
  • 26
21

const express = require('express');
let app = express();
app.use(express.json());

This app.use(express.json) will now let you read the incoming post JSON object

SuRa
  • 1,053
  • 9
  • 13
18

Sometimes you don't need third party libraries to parse JSON from text. Sometimes all you need it the following JS command, try it first:

        const res_data = JSON.parse(body);
xims
  • 1,570
  • 17
  • 22
  • 6
    The original question is about parsing JSON from a POST message in the Express framework. Without the BodyParser middleware, the JSON data will not exist in the body property of the request object. – ThisClark Nov 07 '16 at 02:39
  • 1
    Thank you Hasan, I appreciate your comment. It did helped me when I was looking for solution and came across this post. Not sure if it works in all cases but it definitely works in some and it is a better solution than using third party library. – xims Nov 11 '16 at 00:48
  • 1
    Your answer and a comment provides the answer with more information (the more information being your answer here). You should update your answer to indicate that express needs the body-parser or give an alternative to indicate how body-parser got the data in the first place. – dewwwald Dec 20 '16 at 20:19
  • 3
    does not define `body` – jameshfisher Dec 25 '16 at 08:34
  • But where do I get the string body? – Tomáš Zato Sep 25 '17 at 22:31
  • This is enough to know when you write extensions that took care for parsing for you, for instance, building extension endpoints for directus. – Martin Braun May 31 '21 at 21:15
0

A beginner's mistake...i was using app.use(express.json()); in a local module instead of the main file (entry point).

Hatim
  • 417
  • 6
  • 8
0

Try adding this before your app.post(). I used fetch() instead of axios(), and I forgot to add the JSON parser.

app.use(express.urlencoded({ extended: false }));

app.use(express.json());
Tyler2P
  • 2,324
  • 26
  • 22
  • 31