Get rawBody in express

核能气质少年 提交于 2019-12-10 16:00:46

问题


Hello I am trying to retrieve something from the post, and need the rawBody property from the incoming request. How can I retrieve it??

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

I even tried it with connect.bodyParser(), but I still have no luck with it. I am getting undefined for rawBody.

I was reading on the stackoverflow site saying that they had removed the rawBody functionality, but mentioned that it is a quick fix to add it to our own middleware file. I am a newbie, so I do not have a clue as to how to achieve this. Below is my code snippet.

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

Thank you.


回答1:


You can use your own middle ware to do 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);
})



回答2:


I'm back again :D. After read the connect.bodyParser I've found something: The bodyParser only parse the data which mime type is one of: application/json, application/x-www-form-urlencoded and multipart/form-data. So I think this is another approach, it's not generally elegant but acceptable: When you try to send raw data to server, change the mime type to something different. As your question it's a string, so I choose text/plain as example:

// if the request's 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've tested it via 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: 
{}

It's not actually integrate your middle ware to bodyParser, just make them work together.




回答3:


Building on @Rikky's solution, the way to avoid a race condition in the data event handlers is to continue calling the middleware chain immediately after setting the handlers. Don't wait for req.on('end') to call next(), because that next() call is what allows the json body parser to register its own data and end handlers; if you wait until end is triggered on the request, they'll miss all the relevant events. Instead, use promises:

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();


来源:https://stackoverflow.com/questions/17644836/get-rawbody-in-express

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!