319

I have the following Node.js code:

var express = require('express');
var app = express.createServer(express.logger());
app.use(express.bodyParser());

app.post('/', function(request, response) {
    response.write(request.body.user);
    response.end();
});

Now if I POST something like:

curl -d user=Someone -H Accept:application/json --url http://localhost:5000

I get Someone as expected. Now, what if I want to get the full request body? I tried doing response.write(request.body) but Node.js throws an exception saying "first argument must be a string or Buffer" then goes to an "infinite loop" with an exception that says "Can't set headers after they are sent."; this also true even if I did var reqBody = request.body; and then writing response.write(reqBody).

What's the issue here?

Also, can I just get the raw request without using express.bodyParser()?

Walter Roman
  • 4,621
  • 2
  • 32
  • 36
TheBlueSky
  • 5,526
  • 7
  • 35
  • 65
  • It seems there is something with `response.write(reqBody)`; when I use `response.send(reqBody)` things are working fine... and yes, I use `response.end` after `response.write`. – TheBlueSky Jul 24 '12 at 17:04

17 Answers17

437

Starting from express v4.16 there is no need to require any additional modules, just use the built-in JSON middleware:

app.use(express.json())

Like this:

const express = require('express')

app.use(express.json())    // <==== parse request body as JSON

app.listen(8080)

app.post('/test', (req, res) => {
  res.json({requestBody: req.body})  // <==== req.body will be a parsed JSON object
})

Note - body-parser, on which this depends, is already included with express.

Also don't forget to send the header Content-Type: application/json

rustyx
  • 80,671
  • 25
  • 200
  • 267
  • 22
    Thank you, this is the best answer for 4.16+ then. No other dependencies and works like a charm! – codepleb Jul 18 '18 at 10:06
  • 3
    The best/only solution I could find that does not need the body-parser – Mote Zart Jan 28 '19 at 05:21
  • 1
    I didn't need `body-parser` but instead the built-in `app.use(express.json())`. And then it was the presence of `-H "Content-Type: application/json"` in `curl` request that finally made it work. – daparic Mar 01 '22 at 18:29
  • body-parser has been deprecated now so this is the best answer. – Melaz Apr 13 '22 at 04:31
205

Express 4.0 and above:

$ npm install --save body-parser

And then in your node app:

const bodyParser = require('body-parser');
app.use(bodyParser);

Express 3.0 and below:

Try passing this in your cURL call:

--header "Content-Type: application/json"

and making sure your data is in JSON format:

{"user":"someone"}

Also, you can use console.dir in your node.js code to see the data inside the object as in the following example:

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

app.use(express.bodyParser());

app.post('/', function(req, res){
    console.dir(req.body);
    res.send("test");
}); 

app.listen(3000);

This other question might also help: How to receive JSON in express node.js POST request?

If you don't want to use the bodyParser check out this other question: https://stackoverflow.com/a/9920700/446681

dthree
  • 19,847
  • 14
  • 77
  • 106
Hector Correa
  • 26,290
  • 8
  • 57
  • 73
  • I tried using `curl -d {"user":"Someone"} -H "Content-Type: application/json" --url http://localhost:5000` but it was giving me error "*Unexpected token u*", that's why I switched to the mentioned call in my original post. – TheBlueSky Jul 24 '12 at 17:10
  • I'm marking this as answer because of the link http://stackoverflow.com/a/9920700/446681 – TheBlueSky Jul 24 '12 at 17:11
  • 49
    `express.bodyParser()` is deprecated in Express 4.x. Use https://www.npmjs.org/package/body-parser instead. – Luc Oct 05 '14 at 20:57
  • @TheBlueSky the reason why you got "Unexpected token u" was because the shell consumed your double quotes. The same thing happens if you do `echo any"thing"`. The data you are posting should be within quotes to prevent this from happening. – Tom Fenech Oct 16 '17 at 15:47
  • 17
    From express 4.16.0 or above it's possible to use express.json() in app.use() in this way => app.use(express.json()); – Mitro Mar 27 '18 at 14:16
  • More infos about the deprecation: https://stackoverflow.com/questions/24330014/bodyparser-is-deprecated-express-4 – Armin Šupuk Jun 12 '18 at 19:21
  • I added slash before quote and it worked! `curl -d "{\"user\":\"Someone\"}" -H "Content-Type: application" --url http://localhost:5000` – Linc Apr 25 '19 at 07:36
  • Starting from express v4.16 there is no need to require any additional modules, just use the built-in JSON middleware: express.json() – Flib Feb 08 '22 at 02:19
45

As of Express 4, the following code appears to do the trick. Note that you'll need to install body-parser using npm.

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


app.listen(8888);

app.post('/update', function(req, res) {
    console.log(req.body); // the posted data
});
Walter Roman
  • 4,621
  • 2
  • 32
  • 36
  • 32
    For parsing json bodies it's required to add the following line `app.use(bodyParser.json())` – Camilo Silva Nov 08 '15 at 02:55
  • 1
    @cml.co is there any reason `app.use(bodyParser.urlencoded({ extended: true })` is _also_ required? I am posting a rather complex document as JSON in the request, and `extended: false` did not work. Only when I set it to true, the request is correctly parsed. – Web User Jul 05 '16 at 21:14
  • 4
    Just a note. Had to use `app.use(bodyParser.urlencoded({ extended: true }));` AND `app.use(bodyParser.json())` to get json data on an AWS Linux server setup with NodeJS and Express. – David Dec 08 '16 at 20:21
39

For 2019, you don't need to install body-parser.

You can use:

var express = require('express');
var app = express();
app.use(express.json())
app.use(express.urlencoded({extended: true}))
app.listen(8888);
app.post('/update', function(req, res) {
    console.log(req.body); // the posted data
});
ross
  • 2,684
  • 2
  • 13
  • 22
Shivam Gupta
  • 533
  • 4
  • 9
32

You should not use body-parser it is deprecated. Try this instead

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

app.use(express.json()) //Notice express.json middleware

The app.use() function is used to mount the specified middleware function(s) at the path which is being specified. It is mostly used to set up middleware for your application.

Now to access the body just do the following

app.post('/', (req, res) => {
  console.log(req.body)
})
Hadi Mir
  • 4,497
  • 2
  • 29
  • 31
27
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json())

var port = 9000;

app.post('/post/data', function(req, res) {
    console.log('receiving data...');
    console.log('body is ',req.body);
    res.send(req.body);
});

// start the server
app.listen(port);
console.log('Server started! At http://localhost:' + port);

This will help you. I assume you are sending body in json.

Gautam
  • 743
  • 7
  • 9
13

This can be achieved without body-parser dependency as well, listen to request:data and request:end and return the response on end of request, refer below code sample. ref:https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/#request-body

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

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

    // push the data to body
    var body = [];
    request.on('data', (chunk) => {
      body.push(chunk);
    }).on('end', () => {
      // on end of data, perform necessary action
      body = Buffer.concat(body).toString();
      response.write(request.body.user);
      response.end();
    });
});
Manivannan
  • 3,074
  • 3
  • 21
  • 32
10

In my case, I was missing to set the header:

"Content-Type: application/json"

Despertaweb
  • 1,672
  • 21
  • 29
  • It was also my case. Other than this, I had to send the payload with `JSON.stringify`. Otherwise I got a `400 Bad Request` response. – ismailarilik Oct 04 '22 at 09:52
4

Try this:

response.write(JSON.stringify(request.body));

That will take the object which bodyParser has created for you and turn it back into a string and write it to the response. If you want the exact request body (with the same whitespace, etc), you will need data and end listeners attached to the request before and build up the string chunk by chunk as you can see in the json parsing source code from connect.

Peter Lyons
  • 142,938
  • 30
  • 279
  • 274
4

The accepted answer only works for a body that is compatible with the JSON format. In general, the body can be accessed using

app.use(
  Express.raw({
    inflate: true,
    limit: '50mb',
    type: () => true, // this matches all content types
  })
);

like posted here. The req.body has a Buffer type and can be converted into the desired format.

For example into a string via:

let body = req.body.toString()

Or into JSON via:

let body = req.body.toJSON();
newandlost
  • 935
  • 2
  • 10
  • 21
3

If you're lazy enough to read chunks of post data. you could simply paste below lines to read json.

Below is for TypeScript similar can be done for JS as well.

app.ts

 import bodyParser from "body-parser";
 // support application/json type post data
 this.app.use(bodyParser.json());
 // support application/x-www-form-urlencoded post data
 this.app.use(bodyParser.urlencoded({ extended: false }));

In one of your any controller which receives POST call use as shown below

userController.ts

 public async POSTUser(_req: Request, _res: Response) {
   try {
          const onRecord = <UserModel>_req.body;
           /* Your business logic */
           _res.status(201).send("User Created");
        }
    else{
           _res.status(500).send("Server error");
           }        
   };

_req.body should be parsing you json data into your TS Model.

Shujaath Khan
  • 1,304
  • 16
  • 22
  • 2
    I'm not sure if you're trying to encourage or discourage people to use your answer by calling them lazy :) – TheBlueSky Mar 03 '19 at 06:41
  • Could not figure out how to access my custom body params using `@types/express` for hours. You saved me with that `_req.body`! – umbe1987 Jul 30 '21 at 22:36
2

I'm absolutely new to JS and ES, but what seems to work for me is just this:

JSON.stringify(req.body)

Let me know if there's anything wrong with it!

balintn
  • 988
  • 1
  • 9
  • 19
2

Install Body Parser by below command

$ npm install --save body-parser

Configure Body Parser

const bodyParser = require('body-parser');
app.use(bodyParser);
app.use(bodyParser.json()); //Make sure u have added this line
app.use(bodyParser.urlencoded({ extended: false }));
Arunachalam k
  • 734
  • 1
  • 7
  • 20
1

for people who dont want to use express JSON middleware because they need to be more flexible: you can use the raw nodejs api for it.

How to call it:

const body = await getBody(request);

the function:

function getBody(request) {
  return new Promise((resolve, reject) => {
    const bodyParts = [];

    request.on('error', (error) => {
      console.log(error);
      reject(error);
    })
    
    request.on('data', (chunk) => {
      bodyParts.push(chunk);
    })
    
    request.on('end', () => {
      const body = Buffer.concat(bodyParts).toString();
      resolve(body);
    });
  });
}

source, but converted to promise to be awaitable: https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction

for typescript: the type of chunk is Buffer and of bodyParts it is Buffer[]

Welcor
  • 2,431
  • 21
  • 32
1

Note that if you put your request with a form the Content-type is application/x-www-form-urlencoded You could use a middleware, as of Express 4.16, like app.use(express.json()) but in this way doesn't work because it expects application\json: in that case to change the content-type of your POST request you have to use Ajax. Another way is to use another middleware like that:

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

where the content-type is the same of the form by default.

Nick
  • 1,439
  • 2
  • 15
  • 28
0

What you claim to have "tried doing" is exactly what you wrote in the code that works "as expected" when you invoke it with curl.

The error you're getting doesn't appear to be related to any of the code you've shown us.

If you want to get the raw request, set handlers on request for the data and end events (and, of course, remove any invocations of express.bodyParser()). Note that the data events will occur in chunks, and that unless you set an encoding for the data event those chunks will be buffers, not strings.

ebohlman
  • 14,795
  • 5
  • 33
  • 35
  • that was a copy-paste mistake; I meant `request.body` and not `request.body.user`, and I corrected it now. By the way, the `var reqBody = request.body;` was and still correct and when you try it you'll get the error I'm getting. Anyway, can you please give an example about setting the handler on `request`; I don't seem to find it in express guide. – TheBlueSky Jul 24 '12 at 11:44
-4

You use the following code to log post data:

router.post("/users",function(req,res){
    res.send(JSON.stringify(req.body, null, 4));
});
Chandra Kumar
  • 4,127
  • 1
  • 17
  • 25