Body-Parser:一個格式化請求體數據的 Express 三方庫
body-parser 是 Express 中用于格式化請求體數據的一個三方庫。
以下是一個 body-parser 的常用使用案例。
const express = require('express')
const bodyParser = require('body-parser')
const app = express()
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
app.use(function (req, res) {
res.setHeader('Content-Type', 'text/plain')
res.write('you posted:\n')
res.end(JSON.stringify(req.body, null, 2))
})
以上代碼設置的含義是:項目中所有 Content-Type 是 "application/x-www-form-urlencoded" 或 "application/json" 請求數據都會經過 body-parser 中間件的處理,并設置到 req.body 屬性上。
下面就來詳細介紹 body-parser 的安裝和使用。
安裝
$ npm install body-parser
使用也比較簡單。
const bodyParser = require('body-parser')
我們是通過調用 bodyParser 對象的方法來獲取不同 Content-Type 的數據處理能力的。下面就來介紹。
API
bodyParser 上一共提供了 4 個方法來使用,分別對應 4 種不同類型的請求體數據。
- bodyParser.json([options])
- bodyParser.urlencoded([options])
- bodyParser.text([options])
- bodyParser.raw([options])
其中前 2 種是我們最常使用的。接下來分別介紹。
bodyParser.json([options])
返回能解析 json 數據的中間件,默認匹配 Content-Type 值為 "application/json"(可以通過 options.type 進行控制)。接受任何 Unicode 編碼的請求體數據,而且還支持 gzip 和 deflate 壓縮算法的自動解壓。
解析好的請求體數據會放在 req.body 屬性上,無請求體數據則返回一個空對象({})。
Options 選項
這是一個可選參數,不傳入則使用默認選項。其他 3 個方法與此類似,在此講 1 遍后,如果沒有特殊情況,后面就不再贅述了。
- type:默認值是 "application/json",表示這個中間件默認匹配的 Content-Type 是 "application/json",這個字段除了接收字符串,還支持接收對象和數組。你也可以自定義,比如設置成 "*/json"(內部是使用 type-is[1] 做匹配的)
- inflate:是否開啟自動解壓請求體數據的能力,默認為 true(目前支持 支持 gzip 和 deflate 2 中壓縮算法)
- limit:控制最大請求正文大小,否則報錯。默認值是 '100kb'(內部傳遞給 bytes[2] 庫將其解析成字節數進行判斷處理)
- reviver:body-parser 內部默認使用 JSON.parse() 方法將字符串格式化成對象設置到 req.body 上。這個參數就是傳遞給 JSON.parse() 方法的第 2 個參數,用來自定義解析行為。搞不清楚的同學可以看一下 MDN 上 JSON.parse() 的使用文檔[3]
- strict:默認為 true,用來控制內部 JSON.parse() 所接收的字符串是否只能是對象和數組。設置成 false 時表示可以接受任意類型的字符串數據
bodyParser.urlencoded([options])
默認處理 Content-Type 值為 "application/x-www-form-urlencoded" 的請求體數據。
.urlencoded() 中間件還提供了一個布爾參數 urlencoded,用來決定使用哪一個查詢解析庫來處理請求參數。
- urlencoded為 false 時,內部使用 querystring 庫解析
- urlencoded為 true 時,內部使用 qs 庫解析
qs 與 querystring 的區別在于:querystring 只能解析簡單 key-value 對,qs 則支持嵌套對象的 key-value 對的解析,后者功能會更加強大。
Options 選項
- urlencoded:以上已介紹過。默認為 true(即使用 qs 解析參數),不過已被棄。官方推薦顯式傳入一個值,這就需要你了解 qs 和 querystring 之間的區別
- parameterLimit:控制 URL 編碼數據中允許的最大參數數量,默認是 1000。多于這個值,會向客戶端返回 413 響應碼
bodyParser.text([options])
默認處理 Content-Type 值為 "text/plain" 的請求體數據。
Options 選項
- defaultCharset:如果請求頭中的 Content-Type 頭中沒有指定字符集,則使用這個字段所指定的文本內容的默認字符集。默認為 "utf-8"。
bodyParser.raw([options])
默認處理 Content-Type 值為 "application/octet-stream" 的請求體數據。
不支持 multipart/form-data
body-parser 并不支持處理 Content-Type 是 "multipart/form-data" 的請求體數據。如果你有這方面的需求,可以參照下面的庫進行選擇。
- busboy[4] 和 connect-busboy[5]
- multiparty[6] 和 connect-multiparty[7]
- formidable[8]
- multer[9]
express 已內置 body-parser
express 從 v4.17.0 開始[10],已全面內置了 body-parser 功能,你直接可以通過 express().json() / express().raw()/express().text()/ express().urlencoded() 4 個 API。
在內部,這 4 方法其實是 body-parser 借著 express 暴露出來[11]的。也就是說項目中你無需安裝 body-parser 依賴了。
const bodyParser = require('body-parser')
/**
* Expose middleware
*/
exports.json = bodyParser.json
exports.query = require('./middleware/query');
exports.raw = bodyParser.raw
exports.text = bodyParser.text
exports.urlencoded = bodyParser.urlencoded
總結
本文介紹了 Express 中用于解析請求體數據的中間件 body-parser。 其實 Express 在 v4.17.0 中已完整內置了 body-parser 的能力,你可以通過 express() 上的 .json()/.urlencoded()/.text()/.raw() 方法訪問到。
就介紹到這里了,希望本文對你有所幫助,感謝閱讀,再見。
參考資料
[1]type-is: https://www.npmjs.org/package/type-is#readme
[2]bytes: https://www.npmjs.com/package/bytes
[3]MDN 上 JSON.parse() 的使用文檔: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Example.3A_Using_the_reviver_parameter
[4]busboy: https://www.npmjs.org/package/busboy#readme
[5]connect-busboy: https://www.npmjs.org/package/connect-busboy#readme
[6]multiparty: https://www.npmjs.org/package/multiparty#readme
[7]connect-multiparty: https://www.npmjs.org/package/connect-multiparty#readme
[8]formidable: https://www.npmjs.org/package/formidable#readme
[9]multer: https://www.npmjs.org/package/multer#readme
[10]從 v4.17.0 開始: https://expressjs.com/en/4x/api.html#express.json
[11]body-parser 借著 express 暴露出來: https://github.com/expressjs/express/blob/4.18.2/lib/express.js#L78