Expressjs raw body

node.jsExpress

node.js Problem Overview


How can I access raw body of request object given to me by expressjs?

var express = require('./node_modules/express');
var app = express.createServer();
app.post('/', function(req, res)
{
	console.log(req.body); //says 'undefined'
});
app.listen(80);

node.js Solutions


Solution 1 - node.js

Something like this should work:

var express = require('./node_modules/express');
var app = express.createServer();
app.use (function(req, res, next) {
    var data='';
    req.setEncoding('utf8');
    req.on('data', function(chunk) { 
       data += chunk;
    });
    
    req.on('end', function() {
        req.body = data;
        next();
    });
});

app.post('/', function(req, res)
{
    console.log(req.body);
});
app.listen(80);

Solution 2 - node.js

Using the bodyParser.text() middleware will put the text body in req.body.

app.use(bodyParser.text({type: '*/*'}));

If you want to limit processing the text body to certain routes or post content types, you can do that too.

app.use('/routes/to/save/text/body/*', bodyParser.text({type: 'text/plain'})); //this type is actually the default
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));

If you want a raw Buffer, you can use bodyParse.raw().

app.use(bodyParser.raw({type: '*/*'}));

Note: this answer was tested against node v0.12.7, express 4.13.2, and body-parser 1.13.3.

Solution 3 - node.js

Put the following middleware before bodyParser middleware. It'll collect raw body data in request.rawBody and won't interfere with bodyParser.

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

Solution 4 - node.js

Default express does not buffer data unless you add middleware to do so. The simple solution is to follow the example in @Stewe's answer below, which would just concatenate all of the data yourself. e.g.

var concat = require('concat-stream');
app.use(function(req, res, next){
  req.pipe(concat(function(data){
    req.body = data;
    next();
  }));
});

The downside of this is that you have now moved all of the POST body content into RAM as a contiguous chunk, which may not be necessary. The other option, which is worth considering but depends on how much data you need to process in the post body, would be to process the data as a stream instead.

For example, with XML you could use an XML parser that supports parsing XML as it comes in as chunks. One such parser would be XML Stream. You do something like this:

var XmlStream = require('xml-stream');

app.post('/', function(req, res) {
  req.setEncoding('utf8');
  var xml = new XmlStream(req);
  xml.on('updateElement: sometag', function(element) {
    // DO some processing on the tag
  });
  xml.on('end', function() {
    res.end();
  });
});

Solution 5 - node.js

app.use(bodyParser.json({
    verify: function (req, res, buf, encoding) {
        req.rawBody = buf;
    }
}));
app.use(bodyParser.urlencoded({
    extended: false,
    verify: function (req, res, buf, encoding) {
        req.rawBody = buf;
    }
}));

Solution 6 - node.js

So, it seems like Express's bodyParser only parses the incoming data, if the content-type is set to either of the following:

  1. application/x-www-form-urlencoded
  2. application/json
  3. multipart/form-data

In all other cases, it does not even bother reading the data.

You can change line no. 92 of express/node_modules/connect/lib/middleware/bodyParser.js from

} else {
	    next();
}

To:

} else {
	    var data='';
	    req.setEncoding('utf8');
	    req.on('data', function(chunk) { 
	       data += chunk;
	    });

	    req.on('end', function() {
	        req.rawBody = data;
	        next();
	    });
}

And then, read req.rawBody from your code.

Solution 7 - node.js

If you want the body as a buffer:

var rawParser = function(req, res, next) {
    var chunks = [];
    req.on('data', function(chunk) { 
        chunks.push(chunk)
    });
    req.on('end', function() {
        req.body = Buffer.concat(chunks);
        next();
    });
}

or

var rawParser = bodyParser.raw({type: '*/*'});

and then:

app.put('/:name', rawParser, function(req, res) {
  console.log('isBuffer:', Buffer.isBuffer(req.body));
})

or for all routes:

app.use(bodyParser.raw({type: '*/*'}));

Solution 8 - node.js

It seems this has become a lot easier now!

The body-parser module is able to parse raw and text data now, which makes the task a one-liner:

app.use(bodyParser.text({type: 'text/plain'}))

OR

app.use(bodyParser.raw({type: 'application/binary'}))

Both lines simply fill the body property, so get the text with res.body. bodyParser.text() will give you the UTF8 string while bodyParser.raw() will give you the raw data.

This is the full code for text/plain data:

var express = require('express')
var bodyParser = require('body-parser')
var app = express()
 
app.use(bodyParser.text({type: 'text/plain'}))
 
app.post('/', function (req, res, next) {
    console.log('body:\n' + req.body)

    res.json({msg: 'success!'})

    next()
})

See here for the full documentation: https://www.npmjs.com/package/body-parser

I used express 4.16 and body-parser 1.18

Solution 9 - node.js

If you are having trouble with the above solutions interfering with normal post requests, something like this might help:

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

More info & source: https://github.com/visionmedia/express/issues/897#issuecomment-3314823

Solution 10 - node.js

BE CAREFUL with those other answers as they will not play properly with bodyParser if you're looking to also support json, urlencoded, etc. To get it to work with bodyParser you should condition your handler to only register on the Content-Type header(s) you care about, just like bodyParser itself does.

To get the raw body content of a request with Content-Type: "text/xml" into req.rawBody you can do:

app.use(function(req, res, next) {
  var contentType = req.headers['content-type'] || ''
    , mime = contentType.split(';')[0];

  if (mime != 'text/xml') {
    return next();
  }

  var data = '';
  req.setEncoding('utf8');
  req.on('data', function(chunk) {
    data += chunk;
  });
  req.on('end', function() {
    req.rawBody = data;
    next();
  });
});

Solution 11 - node.js

All the answers seems outdated, if anyone still struggling with this then express has built-in Express raw middeware.

> This middleware is available in Express v4.16.0 onwards. > This is a built-in middleware function in Express. It parses incoming requests with JSON payloads and is based on body-parser.

var express = require("express");
var app = express();

app.use(express.raw({ type: "*/*" }))

app.post("/", (req, res) => {
  // req.body = JSON.parse(req.body); // To parse JSON if needed (in-case)
  console.log(req.body);
  res.end();
});

app.listen(3000, (err) => {
if(!err) console.log("App running!!")
});

Solution 12 - node.js

When sending the request be sure to add this header:

'Content-Type': 'application/json'

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAndrey KonView Question on Stackoverflow
Solution 1 - node.jssteweView Answer on Stackoverflow
Solution 2 - node.jsAaron SilvermanView Answer on Stackoverflow
Solution 3 - node.jsRob ZombieView Answer on Stackoverflow
Solution 4 - node.jsloganfsmythView Answer on Stackoverflow
Solution 5 - node.jspoordeveloperView Answer on Stackoverflow
Solution 6 - node.jsTarandeep GillView Answer on Stackoverflow
Solution 7 - node.jsBernardo RamosView Answer on Stackoverflow
Solution 8 - node.jsJCH2kView Answer on Stackoverflow
Solution 9 - node.jsTechplexEngineerView Answer on Stackoverflow
Solution 10 - node.jsnortronView Answer on Stackoverflow
Solution 11 - node.jsDeepakPixelView Answer on Stackoverflow
Solution 12 - node.jsjobimaView Answer on Stackoverflow