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請求,那可就要注意了)。對象