http://blog.csdn.net/yanyang1116/article/details/54847560
body-parser Node.js(Express) HTTP請求體解析中間件
2016年06月08日 781 聲明
在HTTP請求中,
POST
、
PUT
和
PATCH
三種請求方法中包含請求體,Node.js 原生HTTP子產品中,請求體要基于流的方式接收和解析。
body-parser
是一個HTTP請求體解析中間件,使用這個子產品可以解析JSON、Raw、文本、URL-encoded格式的請求體,
Express
架構中就是使用這個子產品做為請求體解析中間件。
- 請求體解析
- 1.1 原生環境中的解析
- 1.2 使用
解析請求體body-parser
- 請求體解析
- 2.1
- 解析JSON格式bodyParser.json()
- 2.2
- 解析二進制格式bodyParser.raw()
- 2.3
- 解析文本格式bodyParser.text()
- 2.4
- 解析文本格式bodyParser.urlencoded()
- 2.1
1. 請求體解析
1.1 原生環境中的解析
Node.js 原生HTTP子產品中,是将使用者請求資料封裝到了用于請求對象
req
中,該對象是一個
IncomingMessage
,該對象同時也是一個可讀流對象。在原生HTTP伺服器,或不依賴第三方解析子產品時,可以像下面這樣接收并解析請求體:
const http = require('http');
//用http子產品建立一個http服務端
http.createServer(function(req, res) {
if (req.method.toLowerCase() === 'post') {
var body = '';
req.on('data', function(chunk){
body += chunk;
});
req.on('end', function(){
if(req.headers['content-type'].indexOf('application/json')!==-1){
// JSON 格式請求體解析
JSON.parse(body);
} else if(req.headers['content-type'].indexOf('application/octet-stream')!==-1){
// Raw 格式請求體解析
// ……
} else if(req.headers['content-type'].indexOf('text/plain')!==-1){
// text 文本格式請求體解析
// ……
} else if(req.headers['content-type'].indexOf('application/x-www-form-urlencoded')!==-1){
// URL-encoded 格式請求體解析
// ……
} else {
// 其它格式解析
}
})
} else {
res.end('其它送出方式');
}
}).listen(3000);
1.2 使用 body-parser
解析請求體
body-parser
body-parser
子產品是一個
Express/Connect
中間件,它使用非常簡單且功能強大,可以像下面這樣用這個子產品解析請求體:
Express/Connect 項層處理
Express
架構預設使用
body-parser
做為請求體解析中間件,建立Express項目後,可以在
app.js
檔案中看到如下代碼:
/* 引入依賴項 */
var express = require('express');
// ……
var bodyParser = require('body-parser');
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
// ……
// 解析 application/json
app.use(bodyParser.json());
// 解析 application/x-www-form-urlencoded
app.use(bodyParser.urlencoded());
這樣就在項目的Application級别,引入了
body-parser
子產品處理請求體。在上述代碼中,子產品會處理
application/x-www-form-urlencoded
、
application/json
兩種内容格式的請求體。經過這個中間件處理後,就可以在所有路由處理器的
req.body
中通路請求參數。
解析Express具體路由
在實際應用中,不同路徑(路由)可能會要求使用者使用不同的内容類型,
body-parser
還支援為單個Express路由添加請求體解析:
var express = require('express')
var bodyParser = require('body-parser')
var app = express()
// 建立 application/json 解析
var jsonParser = bodyParser.json()
// 建立 application/x-www-form-urlencoded 解析
var urlencodedParser = bodyParser.urlencoded({ extended: false })
// POST /login 擷取 URL編碼的請求體
app.post('/login', urlencodedParser, function (req, res) {
if (!req.body) return res.sendStatus(400)
res.send('welcome, ' + req.body.username)
})
// POST /api/users 擷取 JSON 編碼的請求體
app.post('/api/users', jsonParser, function (req, res) {
if (!req.body) return res.sendStatus(400)
// create user in req.body
})
指定請求類型
body-parser
還支援為某一種或一類内容類型的請求體指定解析方式,指定時可以通過在解析方法中添加
type
參數修改指定
Content-Type
的解析方式。
如,可以對
text/plain
内容類型使用
JSON
解析:
app.use(bodyParser.json({ type: 'text/plain' }))
這一選項更多是用在非标準請求頭的解析中,如下:
// 解析自定義的 JSON
app.use(bodyParser.json({ type: 'application/*+json' }))
// 解析自定義的 Buffer
app.use(bodyParser.raw({ type: 'application/vnd.custom-type' }))
// 将 HTML 請求體做為字元串處理
app.use(bodyParser.text({ type: 'text/html' }))
2. body-parser
子產品的API
body-parser
通過
npm install body-parser
指令安裝子產品後,可以通過以下方式擷取子產品引用:
var bodyParser = require('body-parser')
bodyParser
變量是對中間件的引用。請求體解析後,解析值都會被放到
req.body
屬性,内容為空時是一個
{}
空對象。
2.1 bodyParser.json()
- 解析JSON格式
bodyParser.json()
bodyParser.json(options)
傳回一個僅解析
json
格式資料的中間件。這個方法支援任意Unicode編碼的請求體,且支援
gzip
和
deflate
編碼的資料壓縮。
Option是一個包含以下可選值的對象
-
- 設定為inflate
時,true
壓縮資料會被解壓縮;設定為deflate
時,true
壓縮資料會被拒絕。預設為deflate
。true
-
- 設定請求的最大資料量。預設為limit
'100kb'
-
- 傳遞給reviver
方法的第二個參數,詳見JSON.parse()JSON.parse()
-
- 設定為strict
時,僅會解析true
和Array
兩種格式;設定為Object
會解析所有false
支援的格式。預設為JSON.parse
true
-
- 該選項用于設定為指定MIME類型的資料使用目前解析中間件。這個選項可以是一個函數或是字元串,當是字元串是會使用type-is來查找MIMI類型;當為函數是,中間件會通過type
來擷取實際值。預設為fn(req)
。application/json
-
- 這個選項僅在verify
時受支援verify(req, res, buf, encoding)
2.2 bodyParser.raw()
- 解析二進制格式
bodyParser.raw()
bodyParser.raw(options)
傳回一個将所有資料做為
Buffer
格式處理的中間件。這個方法支援
gzip
和
deflate
編碼的資料壓縮。解析後,其後的所有的
req.body
中将會是一個
Buffer
資料。
Option是一個包含以下可選值的對象
-
- 設定為inflate
時,true
壓縮資料會被解壓縮;設定為deflate
時,true
壓縮資料會被拒絕。預設為deflate
。true
-
- 設定請求的最大資料量。預設為limit
'100kb'
-
- 該選項用于設定為指定MIME類型的資料使用目前解析中間件。這個選項可以是一個函數或是字元串,當是字元串是會使用type-is來查找MIMI類型;當為函數是,中間件會通過type
來擷取實際值。預設為fn(req)
。application/octet-stream
-
- 這個選項僅在verify
時受支援verify(req, res, buf, encoding)
2.3 bodyParser.text()
- 解析文本格式
bodyParser.text()
bodyParser.text(options)
傳回一個僅處理字元串格式處理的中間件。這個方法支援
gzip
和
deflate
編碼的資料壓縮。解析後,其後的所有的
req.body
中将會是一個字元串值。
Option是一個包含以下可選值的對象
-
- 如果defaultCharset
後沒有指定編碼時,使用此編碼。預設為Content-Type
'utf-8'
-
- 設定為inflate
時,true
壓縮資料會被解壓縮;設定為deflate
時,true
壓縮資料會被拒絕。預設為deflate
。true
-
- 設定請求的最大資料量。預設為limit
'100kb'
-
- 該選項用于設定為指定MIME類型的資料使用目前解析中間件。這個選項可以是一個函數或是字元串,當是字元串是會使用type-is來查找MIMI類型;當為函數是,中間件會通過type
來擷取實際值。預設為fn(req)
。application/octet-stream
-
- 這個選項僅在verify
時受支援verify(req, res, buf, encoding)
2.4 bodyParser.urlencoded()
- 解析文本格式
bodyParser.urlencoded()
bodyParser.urlencoded(options)
傳回一個處理
urlencoded
資料的中間件。這個方法預設使用UTF-8編碼,且支援
gzip
和
deflate
編碼的資料壓縮。解析後,其後的所有的
req.body
中将會是一個鍵值對對象。
Option是一個包含以下可選值的對象
-
- 當設定為extended
時,會使用querystring庫解析URL編碼的資料;當設定為false
時,會使用true
庫解析URL編碼的資料。後沒有指定編碼時,使用此編碼。預設為qs
true
-
- 設定為inflate
時,true
壓縮資料會被解壓縮;設定為deflate
時,true
壓縮資料會被拒絕。預設為deflate
。true
-
- 設定請求的最大資料量。預設為limit
'100kb'
-
- 用于設定URL編碼值的最大資料。預設為parameterLimit
1000
-
- 該選項用于設定為指定MIME類型的資料使用目前解析中間件。這個選項可以是一個函數或是字元串,當是字元串是會使用type-is來查找MIMI類型;當為函數是,中間件會通過type
來擷取實際值。預設為fn(req)
。application/octet-stream
-
- 這個選項僅在verify
時受支援verify(req, res, buf, encoding)