Get rawBody in Express

Hello, I'm trying to get something from a message, and I need the rawBody property from the incoming request. How can i get it?

I tried using express.bodyParser () and in my message handler, I was looking for req.rawBody and it was undefined.

I even tried it with connect.bodyParser (), but I still had no luck. I get undefined for rawBody.

I read on the stackoverflow website saying that they removed the rawBody functionality but mentioned that it is a quick solution to add it to our own middleware file. I am a beginner, so I do not know how to do this. The following is a snippet of code.

/** * Module dependencies. */ var express = require('express') , connect = require('connect') , routes = require('./routes') , user = require('./routes/user') , http = require('http') , path = require('path'); var app = express(); // all environments app.set('port', process.env.PORT || 3000); app.set('views', __dirname + '/views'); app.set('view engine', 'jade'); app.use(express.favicon()); app.use(express.logger('dev')); //app.use(express.bodyParser()); app.use(connect.bodyParser()); app.use(express.methodOverride()); app.use(app.router); app.use(express.static(path.join(__dirname, 'public'))); // development only if ('development' == app.get('env')) { app.use(express.errorHandler()); } app.get('/', routes.index); app.get('/users', user.list); /**custom stuff**/ app.post('/upload',function(req, res){ console.log(req.header('Content-Type')); console.log(req.header('Host')); console.log(req.header('User-Agent')); console.log(req.rawBody); console.log(req.body); res.send("<h1> Hello the response is "+req.body.username); }); /** end**/ http.createServer(app).listen(app.get('port'), function(){ console.log('Express server listening on port ' + app.get('port')); }); 

Any help with this is much appreciated.

Thanks.

+4
source share
3 answers

You can use your own middle dish for this:

 app.use(function(req, res, next){ var data = ""; req.on('data', function(chunk){ data += chunk}) req.on('end', function(){ req.rawBody = data; next(); }) }) // Your route registration: app.get('/', function(){// whatever...}) app.post('/test', function(req, res){ console.log(req.rawBody); res.send("your request raw body is:"+req.rawBody); }) 
+7
source

I returned again: D. After reading the connect.bodyParser file, I found something: BodyParser parses only the data that the mime type is one of the following: application / json, application / x-www-form-urlencoded and multipart / form -data. Therefore, I believe that this is another approach, but it is usually not elegant, but acceptable. When you try to send raw data to the server, change the mime type to something else. As your question, this is a string, so I select / plain text as an example:

 // if the request mime type is text/plain, read it as raw data var myRawParser = function(req, res, next){ req.rawData = ''; if(req.header('content-type') == 'text/plain'){ req.on('data', function(chunk){ req.rawData += chunk; }) req.on('end', function(){ next(); }) } else { next(); } } // ... app.use(myRawParser); app.use(express.bodyParser()); // ... // Here is my test route: app.post('/test', function(req, res){ console.log('Mime type is:'+req.header('content-type')); console.log('Raw data is:'+req.rawData); console.log('Body via bodyParser is:'); console.dir(req.body); res.send('Hello!'); }) 

I tested it through curl:

 $ curl -d 'test=hello' 127.0.0.1:3000/test // console result: Mime type is:application/x-www-form-urlencoded Raw data is: Body via bodyParser is: { test: 'hello' } 

and

 $ curl -d 'test=hello' -H 'Content-Type:text/plain' 127.0.0.1:3000/test // console result: Mime type is:text/plain Raw data is:test=hello Body via bodyParser is: {} 

This doesn’t actually integrate your average product into bodyParser, just make them work together.

+2
source

Based on @Rikky's solution, a way to avoid race conditions in data event handlers is to continue to call the middleware chain right after installing the handlers. Do not wait for req.on ('end') to call next (), because this call to next () allows the json body parser to register its own data and end handlers; if you wait until the request completes, they will skip all relevant events. Use promises instead:

 const process = require('process'); const bodyParser = require('body-parser'); const express = require('express'); function main() { const app = express(); app.use((req, res, next) => { req.rawBody = new Promise(resolve => { buf = ''; req.on('data', x => buf += x); req.on('end', () => { resolve(buf); }); }); next(); }); app.use(bodyParser.json()); app.use('/', async (req, res) => { console.log('raw body:', await req.rawBody); console.log('json parsed:', req.body); res.send('bye\n'); }); app.listen('3000', 'localhost', (e) => { if (e) { console.error(e); process.exit(1); } console.log('Listening on localhost:3000'); }); } main(); 
0
source

Source: https://habr.com/ru/post/1491348/


All Articles