403
votes

I have this as configuration of my Express server

app.use(app.router); 
app.use(express.cookieParser());
app.use(express.session({ secret: "keyboard cat" }));
app.set('view engine', 'ejs');
app.set("view options", { layout: true });
//Handles post requests
app.use(express.bodyParser());
//Handles put requests
app.use(express.methodOverride());

But still when I ask for req.body.something in my routes I get some error pointing out that body is undefined. Here is an example of a route that uses req.body :

app.post('/admin', function(req, res){
    console.log(req.body.name);
});

I read that this problem is caused by the lack of app.use(express.bodyParser()); but as you can see I call it before the routes.

Any clue?

30

30 Answers

462
votes

UPDATE July 2020

express.bodyParser() is no longer bundled as part of express. You need to install it separately before loading:

npm i body-parser

// then in your app
var express = require('express')
var bodyParser = require('body-parser')
 
var app = express()
 
// create application/json parser
var jsonParser = bodyParser.json()
 
// create application/x-www-form-urlencoded parser
var urlencodedParser = bodyParser.urlencoded({ extended: false })
 
// POST /login gets urlencoded bodies
app.post('/login', urlencodedParser, function (req, res) {
  res.send('welcome, ' + req.body.username)
})
 
// POST /api/users gets JSON bodies
app.post('/api/users', jsonParser, function (req, res) {
  // create user in req.body
})

See here for further info

original follows

You must make sure that you define all configurations BEFORE defining routes. If you do so, you can continue to use express.bodyParser().

An example is as follows:

var express = require('express'),
    app     = express(),
    port    = parseInt(process.env.PORT, 10) || 8080;

app.configure(function(){
  app.use(express.bodyParser());
});

app.listen(port);
    
app.post("/someRoute", function(req, res) {
  console.log(req.body);
  res.send({ status: 'SUCCESS' });
});
322
votes

Latest versions of Express (4.x) has unbundled the middleware from the core framework. If you need body parser, you need to install it separately

npm install body-parser --save

and then do this in your code

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

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))

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

No. You need to use app.use(express.bodyParser()) before app.use(app.router). In fact, app.use(app.router) should be the last thing you call.

67
votes

Express 4, has build-in body parser. No need to install separate body-parser. So below will work:

export const app = express();
app.use(express.json());
44
votes

First make sure , you have installed npm module named 'body-parser' by calling :

npm install body-parser --save

Then make sure you have included following lines before calling routes

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

app.use(bodyParser.json());
39
votes

The Content-Type in request header is really important, especially when you post the data from curl or any other tools.

Make sure you're using some thing like application/x-www-form-urlencoded, application/json or others, it depends on your post data. Leave this field empty will confuse Express.

36
votes

As already posted under one comment, I solved it using

app.use(require('connect').bodyParser());

instead of

app.use(express.bodyParser());

I still don't know why the simple express.bodyParser() is not working...

30
votes

Add in your app.js

before the call of the Router

const app = express();
app.use(express.json());
22
votes
// Require body-parser (to receive post data from clients)

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

app.use(bodyParser.urlencoded({ extended: false }))

// parse application/json

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

It will help to solve the issue of req.body undefine

13
votes

Looks like the body-parser is no longer shipped with express. We may have to install it separately.

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

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))

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

// parse application/vnd.api+json as json
app.use(bodyParser.json({ type: 'application/vnd.api+json' }))
app.use(function (req, res, next) {
console.log(req.body) // populated!

Refer to the git page https://github.com/expressjs/body-parser for more info and examples.

12
votes

In case anyone runs into the same issue I was having; I am using a url prefix like

http://example.com/api/

which was setup with router

app.use('/api', router); 

and then I had the following

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

What fixed my issue was placing the bodyparser configuration above app.use('/api', router);

Final

// setup bodyparser
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({ extended: true }));

//this is a fix for the prefix of example.com/api/ so we dont need to code the prefix in every route
    app.use('/api', router); 
11
votes

Most of the time req.body is undefined due to missing JSON parser

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

could be missing for the body-parser

const bodyParser  = require('body-parser');
app.use(bodyParser.urlencoded({extended: true}));

and sometimes it's undefined due to cros origin so add them

const cors = require('cors');
app.use(cors())
11
votes

The question is answered. But since it is quite generic and req.body undefined is a frequent error, especially for beginners, I find this is the best place to resume all that I know about the problem.


This error can be caused by the following reasons:

1. [SERVER side] Forget or misused parser middleware

  • You need to use appropriate middleware to parse the incoming requests. For example, express.json() parses request in JSON format, and express.urlencoded() parses request in urlencoded format.
const app = express();
app.use(express.urlencoded())
app.use(express.json())

You can see the full list in the express documentation page

  • You should use the parser middleware before the route declaration part (I did a test to confirm this!). The middleware can be configured right after the initialization express app.

  • Like other answers pointed out, bodyParser is deprecated since express 4.16.0, you should use built-in middlewares like above.

2. [CLIENT side] Forget to send the data along with the request

  • Well, you need to send the data...

To verify whether the data has been sent with the request or not, open the Network tabs in the browser's devtools and search for your request.

  • It's rare but I saw some people trying to send data in the GET request, for GET request req.body is undefined.

3. [SERVER & CLIENT] Using different Content-Type

  • Server and client need to use the same Content-Type to understand each other. If you send requests using json format, you need to use json() middleware. If you send a request using urlencoded format, you need to use urlencoded()...

  • There is 1 tricky case when you try to upload a file using the form-data format. For that, you can use multer, a middleware for handling multipart/form-data.

  • What if you don't control the client part? I had a problem when coding the API for payment IPN. The general rule is to try to get information on the client part: communicate with the frontend team, go to the payment documentation page... You might need to add appropriate middleware based on the Content-Type decided by the client part.

Finally, a piece of advice for full-stack developers :)

When having a problem like this, try to use some API test software like Postman. The object is to eliminate all the noise in the client part, this will help you identify correctly the problem.

In Postman, once you have a correct result, you can use the code generation tool in the software to have corresponded code. The button </> is on the right bar. You have a lot of options in popular languages/libraries... enter image description here

9
votes

express.bodyParser() needs to be told what type of content it is that it's parsing. Therefore, you need to make sure that when you're executing a POST request, that you're including the "Content-Type" header. Otherwise, bodyParser may not know what to do with the body of your POST request.

If you're using curl to execute a POST request containing some JSON object in the body, it would look something like this:

curl -X POST -H "Content-Type: application/json" -d @your_json_file http://localhost:xxxx/someRoute

If using another method, just be sure to set that header field using whatever convention is appropriate.

9
votes

Use app.use(bodyparser.json()); before routing. // . app.use("/api", routes);

9
votes

The middleware is always used as first.

//MIDDLEWARE
app.use(bodyParser.json());
app.use(cors());    
app.use(cookieParser());

before the routes.

//MY ROUTES
app.use("/api", authRoutes);
8
votes

You can try adding this line of code at the top, (after your require statements):

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

As for the reasons as to why it works, check out the docs: https://www.npmjs.com/package/body-parser#bodyparserurlencodedoptions

7
votes

in Express 4, it's really simple

const app = express()
const p = process.env.PORT || 8082

app.use(express.json()) 
6
votes

This occured to me today. None of above solutions work for me. But a little googling helped me to solve this issue. I'm coding for wechat 3rd party server.

Things get slightly more complicated when your node.js application requires reading streaming POST data, such as a request from a REST client. In this case, the request's property "readable" will be set to true and the POST data must be read in chunks in order to collect all content.

http://www.primaryobjects.com/CMS/Article144

6
votes

Wasted a lot of time:

Depending on Content-Type in your client request
the server should have different, one of the below app.use():

app.use(bodyParser.text({ type: 'text/html' }))
app.use(bodyParser.text({ type: 'text/xml' }))
app.use(bodyParser.raw({ type: 'application/vnd.custom-type' }))
app.use(bodyParser.json({ type: 'application/*+json' }))

Source: https://www.npmjs.com/package/body-parser#bodyparsertextoptions

Example:

For me, On Client side, I had below header:

Content-Type: "text/xml"

So, on the server side, I used:

app.use(bodyParser.text({type: 'text/xml'}));

Then, req.body worked fine.

5
votes

To work, you need to app.use(app.router) after app.use(express.bodyParser()), like that:

app.use(express.bodyParser())
   .use(express.methodOverride())
   .use(app.router);
5
votes
var bodyParser = require('body-parser');
app.use(bodyParser.json());

This saved my day.

5
votes

I solved it with:

app.post('/', bodyParser.json(), (req, res) => {//we have req.body JSON
});
4
votes

This issue may be because you have not use body-parser (link)

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

var app = express();
app.use(bodyParser.json());
4
votes

In my case, it was because of using body-parser after including the routes.

The correct code should be

app.use(bodyParser.urlencoded({extended:true}));
app.use(methodOverride("_method"));
app.use(indexRoutes);
app.use(userRoutes);
app.use(adminRoutes);
4
votes

When I use bodyParser it is marked as deprecated. To avoid this I use the following code with express instead of bodyParser.

Notice: the routes must declared finally this is important! Other answers here described the problem well.

const express = require("express");
const app = express();

const routes = require('./routes/api');

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

// Routes must declared finally
app.use('/', routes);
3
votes

You can use express body parser.

var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));
3
votes

If you are using some external tool to make the request, make sure to add the header:

Content-Type: application/json

3
votes

This is also one possibility: Make Sure that you should write this code before the route in your app.js(or index.js) file.

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