[node.js] 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.

This question is related to node.js express

The answer is


My problem was I was creating the route first

// ...
router.get('/post/data', myController.postHandler);
// ...

and registering the middleware after the route

app.use(bodyParser.json());
//etc

due to app structure & copy and pasting the project together from examples.

Once I fixed the order to register middleware before the route, it all worked.


I ran into this problem today, and what fixed it was to remove the content-type header in Postman! Very strange. Adding it here in case it helps someone.

I was following the BeerLocker tutorial here: http://scottksmith.com/blog/2014/05/29/beer-locker-building-a-restful-api-with-node-passport/


I had the same problem a few minutes ago, I tried everything possible in the above answers but any of them worked.

The only thing I did, was upgrade Node JS version, I didn't know that upgrading could affect in something, but it did.

I have installed Node JS version 10.15.0 (latest version), I returned to 8.11.3 and everything is now working. Maybe body-parser module should take a fix on this.


Thank you all for your great answers! Spent quite some time searching for a solution, and on my side I was making an elementary mistake: I was calling bodyParser.json() from within the function :

_x000D_
_x000D_
app.use(['/password'], async (req, res, next) => {_x000D_
  bodyParser.json()_x000D_
  /.../_x000D_
  next()_x000D_
})
_x000D_
_x000D_
_x000D_

I just needed to do app.use(['/password'], bodyParser.json()) and it worked...


I believe this can solve app.use(express.json());


A similar problem happened to me, I simply mixed the order of the callback params. Make sure your are setting up the callback functions in the correct order. At least for anyone having the same problem.

router.post('/', function(req, res){});

I didn't have the name in my Input ... my request was empty... glad that is finished and I can keep coding. Thanks everyone!

Answer I used by Jason Kim:

So instead of

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

I have this

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

In postman, even after following the accepted answer, I was getting an empty request body. The issue turned out to be not passing a header called

Content-Length : <calculated when request is sent>

This header was present by default (along with 5 others) which I have disabled. Enable this and you'll receive the request body.


I was using restify instead of express and ran into the same problem. The solution was to do:

server.use(restify.bodyParser());

Change app.use(bodyParser.urlencoded()); in your code to

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

and in postman, in header change Content-Type value from application/x-www-form-urlencoded to application/json

Ta:-)


Make sure ["key" : "type", "value" : "json"] & ["key":"Content-Type", "value":"application/x-www-form-urlencoded"] is in your postman request headers


You have to check whether the body-parser middleware is set properly to the type of request(json, urlencoded).

If you have set,

app.use(bodyParser.json());

then in postman you have to send the data as raw.

https://i.stack.imgur.com/k9IdQ.png postman screenshot

If you have set,

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

then 'x-www-form-urlencoded' option should be selected.


For express 4.16+, no need to install body-parser, use the following:

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

app.post('/your/path', (req, res) => {
    const body = req.body;
    ...
}

If you are doing with the postman, Please confirm these stuff when you are requesting API

enter image description here


It seems if you do not use any encType (default is application/x-www-form-urlencoded) then you do get text input fields but you wouldn't get file.

If you have a form where you want to post text input and file then use multipart/form-data encoding type and in addition to that use multer middleware. Multer will parse the request object and prepare req.file for you and all other inputs fields will be available through req.body.


you should not do JSON.stringify(data) while sending through AJAX like below.

This is NOT correct code:

function callAjax(url, data) {
    $.ajax({
        url: url,
        type: "POST",
        data: JSON.stringify(data),
        success: function(d) {
            alert("successs "+ JSON.stringify(d));
        }
    });
}   

The correct code is:

function callAjax(url, data) {
    $.ajax({
        url: url,
        type: "POST",
        data: data,
        success: function(d) {
            alert("successs "+ JSON.stringify(d));
        }
    });
}

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' }


Even when i was learning node.js for the first time where i started learning it over web-app, i was having all these things done in well manner in my form, still i was not able to receive values in post request. After long debugging, i came to know that in the form i have provided enctype="multipart/form-data" due to which i was not able to get values. I simply removed it and it worked for me.


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


I solved this using multer as suggested above, but they missed giving a full working example, on how to do this. Basically this can happen when you have a form group with enctype="multipart/form-data". Here's the HTML for the form I had:

<form action="/stats" enctype="multipart/form-data" method="post">
  <div class="form-group">
    <input type="file" class="form-control-file" name="uploaded_file">
    <input type="text" class="form-control" placeholder="Number of speakers" name="nspeakers">
    <input type="submit" value="Get me the stats!" class="btn btn-default">            
  </div>
</form>

And here's how to use multer to get the values and names of this form with Express.js and node.js:

var multer  = require('multer')
var upload = multer({ dest: './public/data/uploads/' })
app.post('/stats', upload.single('uploaded_file'), function (req, res) {
   // req.file is the name of your file in the form above, here 'uploaded_file'
   // req.body will hold the text fields, if there were any 
   console.log(req.file, req.body)
});

My problem was creating the route first require("./routes/routes")(app); I shifted it to the end of the code before app.listen and it worked!


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.


Examples related to node.js

Hide Signs that Meteor.js was Used Querying date field in MongoDB with Mongoose SyntaxError: Cannot use import statement outside a module Server Discovery And Monitoring engine is deprecated How to fix ReferenceError: primordials is not defined in node UnhandledPromiseRejectionWarning: This error originated either by throwing inside of an async function without a catch block dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.62.dylib error running php after installing node with brew on Mac internal/modules/cjs/loader.js:582 throw err DeprecationWarning: Buffer() is deprecated due to security and usability issues when I move my script to another server Please run `npm cache clean`

Examples related to express

UnhandledPromiseRejectionWarning: This error originated either by throwing inside of an async function without a catch block jwt check if token expired Avoid "current URL string parser is deprecated" warning by setting useNewUrlParser to true MongoNetworkError: failed to connect to server [localhost:27017] on first connect [MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017] npm notice created a lockfile as package-lock.json. You should commit this file Make Axios send cookies in its requests automatically What does body-parser do with express? SyntaxError: Unexpected token function - Async Await Nodejs Route.get() requires callback functions but got a "object Undefined" How to redirect to another page in node.js