Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node.js - get raw request body using Express

When I use Express, and my code is:

app.use(express.bodyParser()); 

How would I get the raw request body?

like image 789
haitao_wu Avatar asked Sep 10 '13 03:09

haitao_wu


People also ask

How do I get raw on Body Express?

To get the raw request body, you have to put in some middleware before using the bodyParser. You can also read a GitHub discussion about it here. app. use(function(req, res, next) { req.

How do you use bodyParser in Express?

To use the Text body parser, we have to write app. use(bodyParser. text()) and the Content-Type in your fetch API would be text/html . That's it, now your backend service will accept POST request with text in the request body.

Does body parser come with Express?

The good news is that as of Express version 4.16+, their own body-parser implementation is now included in the default Express package so there is no need for you to download another dependency.


2 Answers

Edit 2: Release 1.15.2 of the body parser module introduces raw mode, which returns the body as a Buffer. By default, it also automatically handles deflate and gzip decompression. Example usage:

var bodyParser = require('body-parser'); app.use(bodyParser.raw(options));  app.get(path, function(req, res) {   // req.body is a Buffer object }); 

By default, the options object has the following default options:

var options = {   inflate: true,   limit: '100kb',   type: 'application/octet-stream' }; 

If you want your raw parser to parse other MIME types other than application/octet-stream, you will need to change it here. It will also support wildcard matching such as */* or */application.


Note: The following answer is for versions before Express 4, where middleware was still bundled with the framework. The modern equivalent is the body-parser module, which must be installed separately.

The rawBody property in Express was once available, but removed since version 1.5.1. To get the raw request body, you have to put in some middleware before using the bodyParser. You can also read a GitHub discussion about it here.

app.use(function(req, res, next) {   req.rawBody = '';   req.setEncoding('utf8');    req.on('data', function(chunk) {      req.rawBody += chunk;   });    req.on('end', function() {     next();   }); }); app.use(express.bodyParser()); 

That middleware will read from the actual data stream, and store it in the rawBody property of the request. You can then access the raw body like this:

app.post('/', function(req, res) {   // do something with req.rawBody   // use req.body for the parsed body }); 

Edit: It seems that this method and bodyParser refuse to coexist, because one will consume the request stream before the other, leading to whichever one is second to never fire end, thus never calling next(), and hanging your application.

The simplest solution would most likely be to modify the source of bodyParser, which you would find on line 57 of Connect's JSON parser. This is what the modified version would look like.

var buf = ''; req.setEncoding('utf8'); req.on('data', function(chunk){ buf += chunk }); req.on('end', function() {   req.rawBody = buf;   var first = buf.trim()[0];   ... }); 

You would find the file at this location:

/node_modules/express/node_modules/connect/lib/middleware/json.js.

like image 193
hexacyanide Avatar answered Sep 29 '22 07:09

hexacyanide


I got a solution that plays nice with bodyParser, using the verify callback in bodyParser. In this code, I am using it to get a sha1 of the content and also getting the raw body.

app.use(bodyParser.json({     verify: function(req, res, buf, encoding) {          // sha1 content         var hash = crypto.createHash('sha1');         hash.update(buf);         req.hasha = hash.digest('hex');         console.log("hash", req.hasha);          // get rawBody                 req.rawBody = buf.toString();         console.log("rawBody", req.rawBody);      } })); 

I am new in Node.js and express.js (started yesterday, literally!) so I'd like to hear comments on this solution.

like image 41
Tiago A. Avatar answered Sep 29 '22 07:09

Tiago A.