542

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?

Rivera
  • 10,792
  • 3
  • 58
  • 102
Masiar
  • 20,450
  • 31
  • 97
  • 140
  • It's not really a solution to your problem but as this is the first thread that results from google I will state it here, make sure there are no other misbehaving middlewares used. – Abdullah Khaled Oct 02 '21 at 08:31

52 Answers52

609

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' });
});
Safin Ghoghabori
  • 516
  • 1
  • 6
  • 17
Mark Bonano
  • 6,482
  • 2
  • 15
  • 12
  • 16
    This worked for me. Note: Unfortunately, some tutorials out there have people (like me) putting routes before app.configure(). In my case this was in the form of app.get/post etc, and a require() including them. – bendman Feb 24 '13 at 21:18
  • 11
    as of express 4, app.use(app.router) is removed. please see the docs https://github.com/visionmedia/express/wiki/New-features-in-4.x – Jonathan Ong Mar 05 '14 at 06:59
  • 18
    as of express 4, middlewares like bodyParser are no longer bundled with Express and must be installed separately. You can find more informations here: https://github.com/senchalabs/connect#middleware. – andrea.rinaldi Sep 09 '14 at 12:38
  • it could be accessed with req.text if content type is text instead of json – Santiago Rebella Mar 16 '15 at 20:44
  • This. Thanks again. All tutorials put their routes before the use. I doubt they test what they write. – blfuentes Jul 06 '18 at 11:11
  • What if the logic of that route is in a separate file?? I think I'm getting the error because the logic is in a separate file. So how should I fix it? – Amirhosein Al Jul 29 '18 at 12:33
  • what does the whole `app.configure` block do in this example? – Sreekar Mouli Oct 02 '18 at 06:41
  • app.configure() is no longer part of Express 4. See here: https://github.com/expressjs/express/wiki/Migrating-from-3.x-to-4.x You no longer need to use app.configure and instead can directly configure your express app – Vibhor Dube Jun 12 '20 at 16:56
  • 1
    looks like your second part was the solution to my problem, I had a mail.js module that was imported before the body-parser. but weird because I added thee body-parser middleware in mail.js itself. – Mendi Sterenfeld Jul 09 '20 at 16:36
  • I think how long will take to rewrite all express tutorials with this important update. Thanks so much. Just a note: should be nice if you invert `urlEncoder post` with `jsonParser`, since you declared those variables in a different order – Leonardo Rick Aug 18 '20 at 16:41
  • Much appreciated! The 2020 update shouldn't use let instead of var? – Federico Cristina Aug 21 '20 at 17:31
  • 3
    From version 4.16.0 Express exposes the json() and urlencoded() middlewares directly from bodyParser, so you can just `import { json } from "express";` if those two middlewares are all you need. Is there a reason why someone shouldn't do this? – nicosemp Dec 11 '21 at 16:19
  • This should be the correct with npm install body-parser --save as the step to save body-parser to package.json – Arunabh Das Dec 25 '22 at 11:03
384

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())
Jay
  • 4,347
  • 1
  • 17
  • 17
  • 4
    I recently updated to express 4.x. Initially when I was trying to log req.body It was showing me undefined. Once I have installed and used body-parser, It is giving me expected req.body values. :) – Alok Adhao Oct 04 '15 at 05:43
  • I found this useful when trying to work out why my POST requests weren't working with json-server. – freethebees Jun 14 '16 at 08:47
  • 4
    `app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()) ` saved me !! – Pramesh Bajracharya Jun 30 '17 at 17:54
  • 7
    While this is true, you must also ensure that the parser configuration takes place before the routes are added. I'd already done the express 4.x thing, but including the routes after the parsing was set up made all the difference to me. – Phil Cairns Oct 27 '17 at 01:07
160

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

export const app = express();
app.use(express.json());
TechTurtle
  • 2,667
  • 4
  • 22
  • 31
107

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.

danmactough
  • 5,444
  • 2
  • 21
  • 22
48

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.

Kevin Xue
  • 756
  • 6
  • 8
  • 15
    +1 This was the problem for me. I was using Postman for Chrome to test a JSON api built in REST, but the object received by Express was empty every time. Turns out Postman by default does **not** automatically add the 'Content-Type: application/json' header even if you select raw > json. – Jordan Sep 29 '13 at 08:20
  • @Jordan +1 Thanks for pointing this out. Indeed I just checked my headers and I see it's still set to 'text/plain' even though I selected 'json'. – Engineer Dec 11 '13 at 20:19
47

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());
jubalm
  • 799
  • 7
  • 8
Ankit kaushik
  • 1,043
  • 10
  • 6
43

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...

nbro
  • 15,395
  • 32
  • 113
  • 196
Masiar
  • 20,450
  • 31
  • 97
  • 140
  • OMG!! You saved my day! I was spending the whole night asking me why express.bodyParser() works for one app, and the same request hangs in another app. YOU'RE A HERO! – faebster May 16 '13 at 02:25
  • 1
    @Masiar This is not working for me. i'm using expressjs 4 & i get error like this. **Error: Cannot find module 'connect'** – Jeyarathnem Jeyachanthuru Jun 14 '14 at 14:23
  • 1
    @JeyTheva mine is a pretty old solution, thus things may have changed in the mean time. I suggest you try to install the `connect` module via `npm install connect` and retry. This is the only thing I can think of by reading the output of your error. – Masiar Jun 17 '14 at 06:29
  • 4
    Here's the latest documentation for solving this issue: https://www.npmjs.com/package/body-parser For others that experience this issue "post express 4", what worked for me was setting the `Content-Type` header to `application/json`. – Grant Eagon Jan 27 '16 at 13:16
  • 3
    Here's the latest documentation for solving this issue: https://www.npmjs.com/package/body-parser After getting body-parser installed, it still didn't work. What did work was setting the `Content-Type` header to `application/json` when I was doing my request. – Grant Eagon Jan 27 '16 at 13:22
  • 1
    `application/json` vs `text/json` in the request works, as suggested by @GrantEagon. – strider Apr 20 '16 at 06:50
  • app.use(express.json()) // convert incomming request to json – John Nico Novero Jun 14 '22 at 01:54
42

Add in your app.js

before the call of the Router

const app = express();
app.use(express.json());
Bourbia Brahim
  • 14,459
  • 4
  • 39
  • 52
Abdesselam
  • 1,001
  • 10
  • 10
  • I tried many solutions mentioned in this post. But this one works. Add app.use(express.json()) before the router. Simple :). Thanks a lot. – iamimran Sep 08 '21 at 14:32
40

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] [Quite often] 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

  • If you can't find the right parser for your request in Express (XML, form-data...), you need to find another library for that. For example, to parse XML data, you can use this library

  • 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] [Rarely] 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] [Quite often] 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 Instant payment notification (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 correctly identify 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

Đăng Khoa Đinh
  • 5,038
  • 3
  • 15
  • 33
35
app.use(express.json());

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

emkarachchi
  • 750
  • 1
  • 7
  • 18
Prashanth K
  • 359
  • 3
  • 4
23
// 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())
parwatcodes
  • 6,669
  • 5
  • 27
  • 39
ASHISH R
  • 4,043
  • 1
  • 20
  • 16
14

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.

Praneesh
  • 363
  • 3
  • 11
  • 1
    This appears to be the new Express 4.x format and worked for me. The express.bodyParser() mentioned in other answers doesn't work in 4.x. – DustinB Nov 21 '14 at 02:30
13

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); 
Jeff Beagley
  • 945
  • 9
  • 19
11

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())
ANIK ISLAM SHOJIB
  • 3,002
  • 1
  • 27
  • 36
11

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);
  • There is no need for it to be placed before other middleware (unless that middleware depends on the body having been parsed, which those examples do not) – Quentin Jan 25 '21 at 15:32
9

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.

ab107
  • 91
  • 1
  • 2
9

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

user1614168
  • 195
  • 2
  • 2
9

History:

Earlier versions of Express used to have a lot of middleware bundled with it. bodyParser was one of the middleware that came with it. When Express 4.0 was released they decided to remove the bundled middleware from Express and make them separate packages instead. The syntax then changed from app.use(express.json()) to app.use(bodyParser.json()) after installing the bodyParser module.

bodyParser was added back to Express in release 4.16.0, because people wanted it bundled with Express like before. That means you don't have to use bodyParser.json() anymore if you are on the latest release. You can use express.json() instead.

The release history for 4.16.0 is here for those who are interested, and the pull request is here.

Okay, back to the point,

Implementation:

All you need to add is just add,

app.use(express.json());
app.use(express.urlencoded({ extended: true}));
app.use(app.router); // Route will be at the end of parser

And remove bodyParser (in newer version of express it is not needed)

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

And Express will take care of your request. :)

Full example will looks like,

const express       = require('express')
const app           = express()

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

app.post('/test-url', (req, res) => {
    console.log(req.body)
    return res.send("went well")
})

app.listen(3000, () => {
    console.log("running on port 3000")
})
Mayur
  • 4,345
  • 3
  • 26
  • 40
9

Firsl of all, ensure you are applying this middleware (express.urlencoded) before routes.

let app = express();

//response as Json
app.use(express.json()); 

//Parse x-www-form-urlencoded request into req.body
app.use(express.urlencoded({ extended: true }));     

app.post('/test',(req,res)=>{
    res.json(req.body);
});

The code express.urlencoded({extended:true}) only responds to x-www-form-urlencoded posts requests, so in your ajax/XMLHttpRequest/fetch, make sure you are sending the request.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); header.

Thats it !

  • this helps a lot. i tried form-data and it always turned out undefined. x-www.form-urlencoded works great. – beginners Jul 15 '22 at 05:36
8

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

in Express 4, it's really simple

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

app.use(express.json()) 
Gerardo Bautista
  • 795
  • 3
  • 11
  • 19
6

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

Masiar
  • 20,450
  • 31
  • 97
  • 140
spikeyang
  • 691
  • 9
  • 17
  • the post mentions HTML form submission as different from REST Client request. aren't both http request ? so, POST is the only case which requires streaming ? – j10 Jun 02 '17 at 03:10
6

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.

Manohar Reddy Poreddy
  • 25,399
  • 9
  • 157
  • 140
6

As I get the same problem, although I know BodyParser is no longer used and I already used the app.use(express.json()) the problem was {FOR ME}: I was placing

app.use(express.json())

after

app.use('api/v1/example', example) => { concerns the route }

once I reorder those two lines;

1 - app.use(express.json())

2 - app.use('api/v1/example', example)

It worked perfectly

Hicham Mounadi
  • 429
  • 6
  • 8
5

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);
HenioJR
  • 604
  • 1
  • 10
  • 17
  • 1
    Your comment and code snippet are contradictory. First you say you have to use `app.use` on `app.router` before `express.bodyParser` but your code clearly indicates it's AFTER. So which is it? – Levi Roberts Aug 21 '14 at 13:11
  • 2
    Sorry man. You need to use app.router after express.bodyParser. – HenioJR Aug 27 '14 at 12:31
5
var bodyParser = require('body-parser');
app.use(bodyParser.json());

This saved my day.

isdot
  • 51
  • 1
  • 4
5

I solved it with:

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

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);
Mo.
  • 26,306
  • 36
  • 159
  • 225
4

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

Content-Type: application/json

Inc33
  • 1,747
  • 1
  • 20
  • 26
4

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());
Inamur Rahman
  • 2,913
  • 1
  • 27
  • 29
4

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());
ari
  • 857
  • 9
  • 10
4

Latest version of Express already has body-parser built-in. So you can use:

const express = require('express);
... 
app.use(express.urlencoded({ extended: false }))
.use(express.json());
LEMUEL ADANE
  • 8,336
  • 16
  • 58
  • 72
4

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);
Marci
  • 302
  • 5
  • 12
4

In express 4 and above you don't need body parser they have their own json parse method, At the higehset level of your express app add

var express = require('express');
var app = express()
app.use(express.json()); //declare this to receive json objects.

Other answers failed to mention, when making the request to express via fetch or other clients. The request must be formatted a certain way.

const response = await fetch(`${expressAddress}/controller/route`, { 
      method: 'POST', // *GET, POST, PUT, DELETE, etc.
      headers: {
          'Content-Type': 'application/json' //this must be set to a json type
      },
      body: JSON.stringify(row) //regular js object need to be converted to json
  })

If you make the fetch request like this the req.body will output your json object as expected.

Greggory Wiley
  • 660
  • 6
  • 16
4

UPDATE 2022

You can just use.

app.use(express.json())

const express = require('express')
const app = express();
const PORT = process.env.PORT || 3001

// Calling the express.json() method for parsing
app.use(express.json())


app.listen(PORT, () => {
    console.log(`============ API Gateway is open at ${PORT} ============= `)
})

express.json() is a built-in middleware function in Express. This method is used to parse the incoming requests with JSON payloads and is based upon the bodyparser.

This method returns the middleware that only parses JSON and only looks at the requests where the content-type header matches the type option.

express.json vs bodyParser.json

John Nico Novero
  • 539
  • 5
  • 10
3

You can use express body parser.

var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));
Kuldeep Mishra
  • 3,846
  • 1
  • 21
  • 26
3

Mine was a text input and I'm adding this answer here regardless so it would help people. Make sure your encoding is set when parsing! I struggled to make it work until I set a proper value to it.

This was the error I was getting without using any parser:

error info: TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object.

Received an instance of undefined at Function.from (buffer.js:327:9)

We do not have to use body-parser now in Express as others have already mentioned, but just that app.use(express.text()); did not solve my issue.

undefined now changed to Object. According to Express documentation, request body returns an empty object ({}) if Content-Type doesn't match (among others).

error info: TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object.

Received an instance of Object at Function.from (buffer.js:327:9)

The encoding type you set needs to be on point as well. In my case, it was text/plain. You can change it to suit your needs like JSON, etc. I did this and voila! Worked like a charm!

app.use(express.text({
    type: "text/plain" 
}));
Saran
  • 1,253
  • 1
  • 9
  • 10
3

Use this line for appropriate parsing at the top before any get or post request is made:

app.use(express.json()) 

This parses json data to Javascript Objects.

Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
Vatsal A Mehta
  • 392
  • 2
  • 15
3

Updated: October 2022

First check or add the body parser using below step:

step :1 import bodyParser from 'body-parser';

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

step 3: most important router shoud be define below of body parser that is the main reason for body undefined....

import noteRouter from "./src/routes/category_routes.js";

app.use(noteRouter);

whatever you name define in router depends on you..

Hope this help you guyz

CHANDAN KUMAR
  • 99
  • 1
  • 1
3

Use either of the two:

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

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

Incase of the 2nd option.

npm i body-parser

const bodyParser = require("body-parser");

Anmol Pal
  • 70
  • 4
2

In case if you post SOAP message you need to use raw body parser:

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

app.use(bodyParser.raw({ type: 'text/xml' }));
opewix
  • 4,993
  • 1
  • 20
  • 42
2

Building on @kevin-xue said, the content type needs to be declared. In my instance, this was only occurring with IE9 because the XDomainRequest doesn't set a content-type, so bodyparser and expressjs were ignoring the body of the request.

I got around this by setting the content-type explicitly before passing the request through to body parser, like so:

app.use(function(req, res, next) {
    // IE9 doesn't set headers for cross-domain ajax requests
    if(typeof(req.headers['content-type']) === 'undefined'){
        req.headers['content-type'] = "application/json; charset=UTF-8";
    }
    next();
})
.use(bodyParser.json());
purpletonic
  • 1,858
  • 2
  • 18
  • 29
2

Credit to @spikeyang for the great answer (provided below). After reading the suggested article attached to the post, I decided to share my solution.

When to use?

The solution required you to use the express router in order to enjoy it.. so: If you have you tried to use the accepted answer with no luck, just use copy-and-paste this function:

function bodyParse(req, ready, fail) 
{
    var length = req.header('Content-Length');

    if (!req.readable) return fail('failed to read request');

    if (!length) return fail('request must include a valid `Content-Length` header');

    if (length > 1000) return fail('this request is too big'); // you can replace 1000 with any other value as desired

    var body = ''; // for large payloads - please use an array buffer (see note below)

    req.on('data', function (data) 
    {
        body += data; 
    });

    req.on('end', function () 
    {
        ready(body);
    });
}

and call it like:

bodyParse(req, function success(body)
{

}, function error(message)
{

});

NOTE: For large payloads - please use an array buffer (more @ MDN)

ymz
  • 6,602
  • 1
  • 20
  • 39
  • the bodyParser package is commonly used and translates the payload into a body object. as provided in other answers – Schuere Jun 15 '17 at 13:32
2

For anyone who none of the answers above have worked for I had to enable cors between my front-end and express.

You can do this either by:

  1. Downloading and turning on a CORS extension for your browser, such as:

    https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi?hl=en

    for Chrome,

or by

  1. Adding the lines

    var cors=require('cors');
    
    app.use(cors());
    

to your express app.js page. (After npm install cors)

Dmitriy Fialkovskiy
  • 3,065
  • 8
  • 32
  • 47
lmb
  • 321
  • 2
  • 7
2

Another possible way to get empty request.body when you forget the name attribute from the input element...

<input type="text" /> /* give back empty request.body -> {}*/
<input type="text" name="username" /> /* give back request.body -> {"username": "your-input"} */
lendoo
  • 332
  • 4
  • 5
2

Simple example to get through all:

Express Code For Method='post' after Login:

This would not require any such bodyParser().

enter image description here

app.js

const express = require('express');
const mongoose = require('mongoose');
const mongoDB = require('mongodb');

const app = express();

app.set('view engine', 'ejs');

app.get('/admin', (req,res) => {
 res.render('admin');
});

app.post('/admin', (req,res) => {
 console.log(JSON.stringify(req.body.name));
 res.send(JSON.stringify(req.body.name));
});

app.listen(3000, () => {
 console.log('listening on 3000');
});

admin.ejs

<!DOCTYPE Html>
<html>
 <head>
  <title>Admin Login</title>
 </head>
 <body>
   <div>
    <center padding="100px">
       <form method="post" action="/admin">
          <div> Secret Key:
            <input name='name'></input>
          </div><br></br><br></br>
          <div>
            <button type="submit" onClick='smsAPI()'>Get OTP</button>
          </div>
       </form>
    </center>
    </div >
</body>
</html>

You get input. The 'name' in "" is a variable that carries data through method='post'. For multiple data input, name='name[]'.

Hence,

on name='name' 

input: Adu
backend: "Adu"

OR

input: Adu, Luv,
backend: "Adu, Luv,"

on

name='name[]'
input: Adu,45689, ugghb, Luv
backend: ["Adu,45689, ugghb, Luv"]
Ank_247shbm
  • 512
  • 7
  • 17
1

adding express.urlencoded({ extended: true }) to the route solves the problem.

router.post('/save',express.urlencoded({ extended: true }),  "your route");
Badr Bellaj
  • 11,560
  • 2
  • 43
  • 44
1
You have to check following things for that:-
1. app.use(bodyParser.urlencoded({ extended: false }))

// parse application/json
app.use(bodyParser.json())
Implement body parser in your app.

2. Check headers in postman its should be based on your rest api's, like if your Content-Type: application/json it should be defined in your postman headers.
ANKIT MISHRA
  • 558
  • 4
  • 13
0

What I did in my case is that I declared app.use(express.json()); app.use(express.urlencoded({ extended: false })); before my routes, and the issue got solved. I hope this helps you too!

0

Try This

npm i multer --save
const express = require('express');
const multer  = require('multer');
const upload = multer();
const app = express();

app.post('/test', upload.any(), (req, res) => {
  console.log('data', req.body);
  res.setHeader('Content-Type', 'application/json');
  res.send(req.body);
});

Merrin K
  • 1,602
  • 1
  • 16
  • 27
-1

In cases where bootstrap classes are used in form definition,getting rid of those classes first helped resolve the issue. I had struggled for some time only to find out the class php-email-form was the culprit.

 <form action="/route/login" method="POST" class="php-email-form row justify-content-center">
MbaiMburu
  • 875
  • 1
  • 10
  • 19
-3

Okay This may sound Dumb but it worked for me.

as a total beginner, I didn't realized that writing:

router.post("/", (res, req) => {
  console.log(req.body);
  req.send("User Route");
});

is wrong !

You have make sure that you pass parameters(req,res) of post/get in right order: and call them accordingly:

router.post("/", (req, res) => {
  console.log(req.body);
  res.send("User Route");
});
  • 2
    That definitely isn't the problem that is being experienced in the question (and if it were, then it would have been closed because we don't answer typo questions around here). – Quentin Jan 25 '21 at 15:31