express项目中一般使用body-parser进行post参数的解析,最经常使用的是其中的json和urlencoded的parser,可分别对以JSON格式的post参数和urlencoeded的post参数进行解析,都可得到一个JSON化的req.body,如:express
{ "username": "user", "password": "pass" }
body-parser还有一个raw parser,能够获取一个buffer对象的req.body。json
经过详细阅读body-parser的源代码,能够知道,各个parser会对req headers及post参数进行一系列的判断和处理,只有知足条件的状况下才对post参数进行解析,解析以前,首先使用raw-body模块对req进行处理,其处理过程是将req做为一个readable stream进行处理,从而获得raw body内容,而后按具体的格式进行解析。app
在express项目中,一般顺序调用body-parser所提供的parser,这样当一个parser没法知足post参数解析条件时,还可使用另外一个parser进行解析(在某些特殊的请求中,有可能全部parser均没法解析)。函数
app.use(bodyParser.raw); app.use(bodyParser.json); app.use(bodyParser.urlencoded({ extended: false });
但body-parser的各个parser在解析的过程当中,若对知足解析条件的post参数进行了解析,req做为一个stream对象,已经被消耗,没法再使用另外一个parser对post参数解析,也即post参数只能被第一个知足解析条件的parser进行解析。所以即便前后调用raw、json、urlencoded这三个parser,也只能获得一个body,具体格式由各parser的调用次序及post参数知足的解析条件决定。JSON化的body和raw body如同鱼与熊掌,两者不可得兼。post
但在有些场合下,可能须要在解析body的同时使用raw body进行其余操做,如某些应用场景下就须要使用raw body参与签名运算以对访问者进行鉴权。大数据
其实body-parser
提供了一个办法在解析post参数的同时获取raw body
,那就是在调用parser的时候传入的参数中带verify回调函数:url
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; } }));
verify参数自己是用于对请求的校验,当校验失败的时候经过抛出error来停止body-parser的解析动做,在这里被借用来实现post参数raw body的获取。code
这样一来,在将post参数解析成JSON化的req.body的同时,body-parser还会将raw body赋值给req.rawBody(固然,内存也占用了两份,这是须要注意的地方,若是应用中有大数据量的POST请求,那可就要注意了)。对象