nodejs之express的中間件


express中間件分成三種

內置中間件 static

自定義中間件
第三方中間件 (body-parser) (攔截器)

 

全局自定義中間件

 

在請求接口時 有幾個接口都要驗證傳來的內容是否存在或者是否正確 不可能每個接口都寫一段驗證,所以這一段驗證可以提取出來,通過中間件實現
const express = require("express");
const app = express();

//  test1接口
app.get("/test1",(req,res) => {
    res.send("test1 ok")
})
//  test2接口
app.get("/test2",(req,res) => {
    res.send("test2 ok")
})
//  開啟服務器
app.listen(2000,() => {
    console.log('開啟在2000端口');
})
現在要做的是在請求test1和test2的時候 看請求中有沒有帶上需要的字段 token
app.use()
第一種中間件 可以說是攔截器
第一個參數是路徑 第二個參數是回調函數 回調函數中有req res next
const express = require("express");
const app = express();

app.use("/",(req,res,next)=>{
    console.log("中間件")
})
//  test1接口
app.get("/test1",(req,res) => {
    console.log('test1');
    res.send("test1 ok")
})
//  test2接口
app.get("/test2",(req,res) => {
    console.log('test2');
    res.send("test2 ok")
})
//  開啟服務器
app.listen(2000,() => {
    console.log('開啟在2000端口');
})

現在在瀏覽器中請求/test1 沒有響應,在終端中打印出來

這個中間件的作用在於 請求/開頭的路徑時 優先走中間件的回調函數 中間件里的next()表示是否繼續往下執行 ,有next()就繼續往下走, 沒有next()就不往下走

 

const express = require("express");
const app = express();

app.use("/",(req,res,next)=>{
    console.log("中間件")
    next()  //  是否繼續往下執行
})
//  test1接口
app.get("/test1",(req,res) => {
    console.log('test1');
    res.send("test1 ok")
})
//  test2接口
app.get("/test2",(req,res) => {
    console.log('test2');
    res.send("test2 ok")
})
//  開啟服務器
app.listen(2000,() => {
    console.log('開啟在2000端口');
})

頁面中

終端打印

簡單來說 在來到/test1接口之前 有個攔截器,這個攔截器中的路徑是/, 所有的接口都先走這個攔截器,在這個攔截器里做邏輯處理,允許它繼續往下走就加next() ,不允許往下走就不用加next(), 因此驗證上文提到的token,就可以在中間件里進行

const express = require("express");
const app = express();

app.use("/",(req,res,next)=>{
    console.log("中間件")
    let {token} = req.query;
    if(token){
        next()  //  是否繼續往下執行
    }else{
        res.send("缺少token")
    }
})
//  test1接口
app.get("/test1",(req,res) => {
    console.log('test1');
    res.send(`test1 token為${req.query.token}`)
})
//  test2接口
app.get("/test2",(req,res) => {
    console.log('test2');
    res.send(`test2 token為${req.query.token}`)
})
//  開啟服務器
app.listen(2000,() => {
    console.log('開啟在2000端口');
})

瀏覽器中訪問/test1 不帶token字段

現在帶上token字段訪問/test2

這就實現了通過中間件做全局攔截,這種中間件屬於自定義攔截器.如果app.use()的第一個參數是 / 表示路徑,則第一個參數可以不寫,如下

app.use("/",(req,res,next)=>{
    next()  //  是否繼續往下執行
})

等同於

app.use((req,res,next)=>{
    next()  //  是否繼續往下執行
})

這也可以說為什么body-parser是一個中間件

const bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({extended:false}))
app.use(bodyParser.json())
在使用bodyParser.json()的時候也是在app.use()方法里跟了一個函數。
中間件的使用 在app.use()里 可以加上一個回調函數,在回調函數里做一些處理 需要注意的是在合適的時機 使用next()繼續執行后面的操作
為什么說這一種是全局的 ,因為所有的接口都走這里 接下來看局部中間件
局部中間件
第一個參數還是路徑 第二個參數是一個function 第三個參數還是function
const express = require("express");
const app = express();

app.get("/demo",(req,res,next) => {
    console.log('fun1');
},(req,res) => {
    console.log('fun2');
})
//  開啟服務器
app.listen(2000,() => {
    console.log('開啟在2000端口');
})
現在請求/demo接口 瀏覽器中沒有響應 因為第一個回調函數里沒有next() 不會走到第二個回調函數里
終端打印

在第一個回調函數中加上next()看看

const express = require("express");
const app = express();

app.get("/demo",(req,res,next) => {
    console.log('fun1');
    next()
},(req,res) => {
    res.send("fun2")
    console.log('fun2');
})
//  開啟服務器
app.listen(2000,() => {
    console.log('開啟在2000端口');
})

瀏覽器中訪問/demo

終端打印

這種叫局部中間件,局部中間件是 在哪個接口里寫就只對哪個接口有用,局部中間件可以寫無數個 只要在合適的地方使用next()就可以一個接一個的往下執行,一般情況下使用局部中間件最多使用一兩個就夠了 使用多個局部中間件 代碼結構如下

app.get("/test",fun1,fun2,fun3,fun4,fun5..)

內置中間件 static 又叫靜態資源目錄
類似於apache的靜態目錄 指定目錄后把圖片 網頁 文件放進去 直接可以訪問到
在項目目錄新建一個文件夾 public 隨便起名,用作靜態資源目錄
只要是中間件都是用app.use()方法
app.use(express.static("./public"))

在public目錄下新建一個index.html文件 寫上內容

瀏覽器訪問/index.html

 

這樣是直接訪問靜態目錄,如果在public目錄下還有目錄,在瀏覽器中地址欄/后輸入public下的目錄的文件也可以訪問到
還有另一種寫法
app.use("/",express.static("./public"))
訪問的地址不變 依然可以打開頁面,因為路徑名字是/時 第一個參數可以省去
如果想定義用戶輸入的路徑 就改第一個參數
app.use("/public/test/",express.static("./public"))

瀏覽器訪問時應該輸/public/test/index.html了

總結 在express中 無論是app.get 還是app.post app.use 只要方法里第一個參數有路徑 都會和瀏覽器訪問的路徑做對比 如果匹配上了就走當前的方法
如果在app.use 和 app.get app.post 的第一個參數中 有相同的路徑 ,當用戶訪問時會優先走到app.use()的方法里 因為app.use()是一個攔截器


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM