Express中間件的理解

中間件函數(shù)能夠訪問請求對象 (req)、響應(yīng)對象 (res) 以及應(yīng)用程序的請求/響應(yīng)循環(huán)中的下一個中間件函數(shù)四濒。下一個中間件函數(shù)通常由名為next的變量來表示。

中間件函數(shù)可以執(zhí)行以下任務(wù):

  • 執(zhí)行任何代碼。
  • 對請求和響應(yīng)對象進行更改存哲。
  • 結(jié)束請求/響應(yīng)循環(huán)母蛛。
  • 調(diào)用堆棧中的下一個中間件函數(shù)翩剪。

如果當(dāng)前中間件函數(shù)沒有結(jié)束請求/響應(yīng)循環(huán),那么它必須調(diào)用next()函數(shù)彩郊,以將控制權(quán)傳遞給下一個中間件函數(shù)前弯。否則蚪缀,請求將保持掛起狀態(tài)。

演示示例:

/**
 * express 中間件使用解析
 */

const express = require('express')

// 本次 http 請求的實例
const app = express()

// 模擬登陸驗證
function loginCheckSuccess(req, res, next) {
  console.log('模擬登陸成功')
  setTimeout(() => {
    next()
  })
}

// 模擬登陸失敗
function loginCheckFailed(req, res, next) {
  console.log('模擬登陸失敗')
  setTimeout(() => {
    res.json({
      errno: -1,
      msg: '登陸失敗'
    })
  })
}

app.use((req, res, next) => {
  console.log('請求開始···', req.method, req.url)
  next()
})

app.use((req, res, next) => {
  // 假設(shè)在處理 cookie
  req.cookie = {
    userID: 'abc123'
  }
  next()
})

app.use((req, res, next) => {
  // 假設(shè)處理 post data
  // 異步
  setTimeout(() => {
    req.body = {
      a: 100,
      b: 200
    }
    next()
  })
})

app.use('/api', (req, res, next) => {
  console.log('處理 /api 路由')
  next()
})

app.get('/api', (req, res, next) => {
  console.log('get /api 路由')
  next()
})

app.post('/api', (req, res, next) => {
  console.log('get /api 路由')
  next()
})

app.get('/api/get-cookie', loginCheckSuccess, (req, res, next) => {
  console.log('get /api/get-cookie')
  res.json({
    errno: 0,
    data: req.cookie 
  })
})

app.post('/api/get-post-deta', loginCheckFailed, (req, res, next) => {
  console.log('post /api/get-post-data')
  res.json({
    error: 0,
    data: res.body
  }) 
})

app.use((req, res, next) => {
  console.log('處理 404')
  res.json({
    error: -1,
    msg: '404 not found'
  })
})

app.listen(3000, () => {
  console.log('server is running on 3000')
})

通過瀏覽器分析get請求

這里使用應(yīng)用層中間件為例恕出,解釋中間件的使用

  • 首先調(diào)用app.use()函數(shù)的中間件询枚,將能夠響應(yīng)任何方法的請求。app.method()函數(shù)將處理對應(yīng)HTTP方法的請求
  • 如果第一個參數(shù)沒有傳入路徑參數(shù)浙巫,將默認解釋為根路徑(/
  • 支持傳入多個中間件函數(shù)金蜀,但為了提高代碼的可讀性,盡量不要超過三個
  1. 首先nodex index.js運行上面的代碼
  2. 在瀏覽器中輸入localhost:3000/api/get-cookie
  3. 瀏覽器返回:{"errno":0,"data":{"userID":"abc123"}}

我們再查看控制臺中的輸出

$ node index.js
server is running on 3000
請求開始··· GET /api/get-cookie
處理 /api 路由
模擬登陸成功
get /api/get-cookie

讓我們來借此分析一下的畴,中間件的運行渊抄。
首先,app.use((req, res, next)...苗傅,這里是通過app.use注冊的抒线,并且沒有指定響應(yīng)路由參數(shù),默認為/渣慕,將響應(yīng)系統(tǒng)的所有路由和方式的請求嘶炭,所以先輸出了這里定義的回調(diào)函數(shù)(請求開始··· GET /api/get-cookie)。
其次逊桦,是第二個使用app.use()的定義的函數(shù)眨猎,定義了req.cookie

app.use((req, res, next) => {
  // 假設(shè)在處理 cookie
  req.cookie = {
    userID: 'abc123'
  }
  next()
})

再次,由于我們訪問的地址為/api/get-cookie强经,這樣會先訪問到他的上級路徑上定義的中間件函數(shù)睡陪,app.get('/api'),所以緊接著輸出了處理 /api 路由匿情。
最后兰迫,進入到app.get('/api/get-cookie')定義的應(yīng)用層中間件。首先依次執(zhí)行loginCheckSuccess()中間件函數(shù)炬称,返回模擬登陸成功汁果,next(),執(zhí)行后面的中間件函數(shù)玲躯,res.json()為服務(wù)器返回了req.cookie中寫入的值据德。

### 通過postman分析post請求

使用postman,在請求地址欄輸入http://127.0.0.1:3000/api/get-post-deta跷车,將返回{"errno":-1,"msg":"登陸失敗"}

其執(zhí)行原理和通過瀏覽器測試get請求類似棘利,都是順序執(zhí)行了app.useapp.post的從根路徑到目標(biāo)路徑上的中間件函數(shù)。不同的是朽缴,這里我們用loginCheckFailed()函數(shù)模擬了登錄失敗善玫,這樣由于登錄失敗,直接向postman中返回錯誤信息密强,將不再執(zhí)行后面的中間件函數(shù)蝌焚。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末裹唆,一起剝皮案震驚了整個濱河市誓斥,隨后出現(xiàn)的幾起案子只洒,更是在濱河造成了極大的恐慌,老刑警劉巖劳坑,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件毕谴,死亡現(xiàn)場離奇詭異,居然都是意外死亡距芬,警方通過查閱死者的電腦和手機涝开,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來框仔,“玉大人舀武,你說我怎么就攤上這事±胝叮” “怎么了银舱?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長跛梗。 經(jīng)常有香客問我寻馏,道長,這世上最難降的妖魔是什么核偿? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任诚欠,我火速辦了婚禮,結(jié)果婚禮上漾岳,老公的妹妹穿的比我還像新娘轰绵。我一直安慰自己,他們只是感情好尼荆,可當(dāng)我...
    茶點故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布左腔。 她就那樣靜靜地躺著,像睡著了一般耀找。 火紅的嫁衣襯著肌膚如雪翔悠。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天野芒,我揣著相機與錄音蓄愁,去河邊找鬼。 笑死狞悲,一個胖子當(dāng)著我的面吹牛撮抓,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播摇锋,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼丹拯,長吁一口氣:“原來是場噩夢啊……” “哼站超!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起乖酬,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤死相,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后咬像,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體算撮,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年县昂,在試婚紗的時候發(fā)現(xiàn)自己被綠了肮柜。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡倒彰,死狀恐怖审洞,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情待讳,我是刑警寧澤芒澜,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站耙箍,受9級特大地震影響撰糠,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜辩昆,卻給世界環(huán)境...
    茶點故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一阅酪、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧汁针,春花似錦术辐、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至猾骡,卻和暖如春瑞躺,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背兴想。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工幢哨, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人嫂便。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓捞镰,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子岸售,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,527評論 2 349

推薦閱讀更多精彩內(nèi)容