1.如何自己動手定制中間件
模擬一個類似于 express.urlencoded 這樣的中間件,來決議 POST 提交到服務器的表單資料
2.實作步驟:
-
定義中間件
-
監聽
req的data事件 -
監聽
req的end事件 -
使用
querystring模塊決議請求體資料 -
將決議出來的資料物件掛載為
req.body -
將自定義中間件封裝為模塊
2.1 定義中間件
使用 app.use() 來定義全域生效的中間件
const express=require('express')
const app=express();
// 決議表單資料的中間件
app.use((req,res,next)=>{
// 定義中間價具體的業務邏輯
})
app.listen(8080,()=>{
console.log('running....')
})
2.2 監聽 req 的 data 事件
(1) 在中間件中,需要監聽req物件的data事件,來獲取客戶端發送到服務器的資料
(2) 如果資料量比較大,無法一次性發送完畢,則客戶端會把資料切割后,分批發送到服務器,所以 data 事件可能會觸發多次,每一次觸發 data 事件時,獲取到資料只是完整資料的一部分,需要手動對接收到的資料進行拼接
//定義變數 ,用來存盤客戶端回應過來的請求資料
let str='';
//監聽req物件的data事件
app.on('data',(chunk)=>{
str+=chunk
})
2.3 監聽req.end()事件
當請求資料接收完畢之后,會自動觸發req的end事件
我們可以在req的end事件中,拿到并處理完整的請求體資料
app.on('end',()=>{
//列印完整的請求體資料
console.log(str)
{)
2.4 用 querystring 模塊決議請求體資料
node.js內置了一個querystring模塊, 專門用來處查詢字串. 通過這個模塊提供的parse ()函式,可以輕松的把查詢字串決議成物件的格式.
//匯入 querystring 模塊
const qs=require('querystring');
//呼叫parse()方法
const body=qs.parse(str)
2.5 將決議出來的資料物件掛載為req.body
上游的中間件和下游的中間件及路由之間,共享同一份 req 和 res,因此,我們可以將決議出來的資料,掛載為 req 的自定義屬性,命名為 req.body,供下游使用.
req.on('end',()=>{
const body=qs.parse(str);
req.body=body;
next()
})
整體代碼:
// 匯入 express 模塊
const express = require('express')
// 創建 express 的服務器實體
const app = express()
// 4. 匯入 Node 內置模塊 querystring
const qs = require('querystring')
// 決議表單資料的中間件
app.use((req, res, next) => {
// 定義中間價具體的業務邏輯
// 1. 定義一個 str 字串,專門用來存盤客戶端發送過來的請求體資料
let str = ''
// 2. 監聽 req 的 data 事件
req.on('data', (chunk) => {
str += chunk
})
// 3. 監聽 req 的 end 事件
req.on('end', () => {
// 在 str 中存放的是完整的請求體資料
console.log(str)
// 將字串格式的請求體資料,決議成物件
// 5. 呼叫 qs.parse() 方法,將查詢字串決議成物件
const body = qs.parse(str)
// 6. 將決議出來的資料物件掛載為 req.body 屬性
req.body = body
next()
})
})
app.post('/user', (req, res) => {
res.send(req.body)
})
// 呼叫 app.listen方法,指定埠號并啟動 web 服務器
app.listen(3000, () => {
console.log('running……')
})
2.6 將自定義中間件封裝為模塊
新建一個 custom-body-parser.js檔案, 將中間件函式,封裝為獨立的模塊
//匯入 Node 內置模塊 querystring
const qs = require('querystring')
// 決議表單資料的中間件
module.exports=function badyParse(req, res, next){
// 定義中間價具體的業務邏輯
// 1. 定義一個 str 字串,專門用來存盤客戶端發送過來的請求體資料
let str = ''
// 2. 監聽 req 的 data 事件
req.on('data', (chunk) => {
str += chunk
})
// 3. 監聽 req 的 end 事件
req.on('end', () => {
// 在 str 中存放的是完整的請求體資料
console.log(str)
// 將字串格式的請求體資料,決議成物件
// 5. 呼叫 qs.parse() 方法,將查詢字串決議成物件
const body = qs.parse(str)
// 6. 將決議出來的資料物件掛載為 req.body 屬性
req.body = body
next()
})
}
對自定義的中間件進行模塊化拆分:
// 匯入 express 模塊
const express = require('express')
// 創建 express 的服務器實體
const app = express()
// 匯入自己封裝的中間件模塊
app.use(require('./custom-body-parser'))
app.post('/user', (req, res) => {
res.send(req.body)
})
// 呼叫 app.listen方法,指定埠號并啟動 web 服務器
app.listen(3000, () => {
console.log('running……')
})
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/308855.html
標籤:其他
下一篇:基于 Express 寫介面
