req.body empty on posts

All of a sudden this has been happening to all my projects.

Whenever I make a post in nodejs using express and body-parser req.body is an empty object.

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

var app = express()

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded())

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

app.listen(2000);

app.post("/", function (req, res) {
  console.log(req.body) // populated!
  res.send(200, req.body);
});

Via ajax and postman it's always empty.

However via curl

$ curl -H "Content-Type: application/json" -d '{"username":"xyz","password":"xyz"}' http://localhost:2000/

it works as intended.

I tried manually setting Content-type : application/json in the former but I then always get 400 bad request

This has been driving me crazy.

I thought it was that something updated in body-parser but I downgraded and it didn't help.

Any help appreciated, thanks.


Solution 1:

In Postman of the 3 options available for content type select "X-www-form-urlencoded" and it should work.

Also to get rid of error message replace:

app.use(bodyParser.urlencoded())

With:

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

See https://github.com/expressjs/body-parser

The 'body-parser' middleware only handles JSON and urlencoded data, not multipart

As @SujeetAgrahari mentioned, body-parser is now inbuilt with express.js.

Use app.use(express.json()); to implement it in recent versions for JSON bodies. For URL encoded bodies (the kind produced by HTTP form POSTs) use app.use(express.urlencoded());

Solution 2:

With Postman, to test HTTP post actions with a raw JSON data payload, select the raw option and set the following header parameters:

Content-Type: application/json

Also, be sure to wrap any strings used as keys/values in your JSON payload in double quotes.

The body-parser package will parse multi-line raw JSON payloads just fine.

{
    "foo": "bar"
}

Tested in Chrome v37 and v41 with the Postman v0.8.4.13 extension (body-parser v1.12.2 and express v4.12.3) with the setup below:

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

// configure the app to use bodyParser()
app.use(bodyParser.urlencoded({
    extended: true
}));
app.use(bodyParser.json());

// ... Your routes and methods here

Postman raw json payload

Solution 3:

I made a really dumb mistake and forgot to define name attributes for inputs in my html file.

So instead of

<input type="password" class="form-control" id="password">

I have this.

<input type="password" class="form-control" id="password" name="password">

Now request.body is populated like this: { password: 'hhiiii' }

Solution 4:

I discovered, that it works when sending with content type

"application/json"

in combination with server-side

app.use(bodyParser.json());

Now I can send via

var data = {name:"John"}
var xmlHttp = new XMLHttpRequest();
xmlHttp.open("POST", theUrl, false); // false for synchronous request
xmlHttp.setRequestHeader("Content-type", "application/json");
xmlHttp.send(data);

and the result is available in request.body.name on the server.