nodejs入門之Express 中間件

Express 中間件

​ Express 是一個路由和中間件Web框架,其自身的功能很少。Express 應用程序本質上是一系列中間件函數調用。

一.簡介

​ 一個請求發送到服務器,要經歷一個生命週期,服務端要: 監聽請求-解析請求-響應請求,服務器在處理這一過程的時候,有時候就很複雜了,將這些複雜的業務拆開成一個個子部分,子部分就是一個個中間件。對於處理請求來說,在響應發出之前,可以對請求和該級響應做一些操作,並且可以將這個處理結果傳遞給下一個處理步驟

​ 簡單說,Express 的中間件(middleware)就是處理HTTP請求的函數。它最大的特點就是,一箇中間件處理完,再傳遞給下一個中間件。App實例在運行過程中,會調用一系列的中間件。

img

​ 每個中間件可以從App實例,接收三個參數,依次爲request對象(代表HTTP請求)、response對象(代表HTTP迴應),next回調函數(代表下一個中間件)。每個中間件都可以對HTTP請求(request對象)進行加工,並且決定是否調用next方法,將request對象再傳給下一個中間件。用下圖更形象點:

img

​ 上圖可以看到,用戶取水的過程,就是一個http請求,然後經過一系列中間件處理,最後得到返回結果的過程.

二.作用

express這樣描述中間件的

1.執行任何代碼。
2.修改請求和響應對象。
3.終結請求-響應循環。
4.調用堆棧中的下一個中間件

三.分類

1.應用級中間件
2.路由級中間件
3.錯誤處理中間件
4.內置中間件
5.第三方中間件
6.自定義中間件

四.使用中間件

1.全局使用

const express = require("express");
const app = express();
/**
 * 全局使用,
 * 注意點,代碼的順序問題
 *  app.use 的語法
 *      app.use(PATH, [...HANDLER])
 *        - PATH 路徑前綴,默認是 /
 *        - HANDLER   中間件函數,可以是多個
 */
app.use((req, res, next) => {
    console.log(1);
    //一定要使用next(),纔會將控制器丟給下箇中間件
    next();
}, (req, res, next) => {
    console.log(2);
    next();
}, (req, res, next) => {
    console.log(4);
    next();
});

app.get('/', (req, res, next) => {
    console.log(3);
    res.send("hello");
});

app.listen(3000, () => {
    console.log("服務啓動成功");
});

2.全局使用時,必須有前綴條件

/**
 * 全局調用中間件,但是有前綴條件
 */

const express = require('express')
const app = express()

//這裏是全局中間件  前綴條件是必須是有/hello的路由
app.use('/hello', (req, res, next) => {
  console.log('中間件1')
  next()
})

// GET http://localhost:3000/
app.get('/', (req, res) => {
  console.log('2')
  res.send('hello')
})

// GET http://localhost:3000/hello/world
app.get('/hello/world', (req, res) => {
  console.log(3)
  res.send('hello 1')
})


app.listen(3000, () => {
  console.log('服務啓動成功')
})

3.針對路由,局部調用中間件

/**
 * 局部調用中間件(針對某個路由單獨去調用)
 */

const express = require('express')
const app = express()

// 1. 定義一箇中間件函數
const hello = (req, res, next) => {
  console.log('hi,大家好,我是渣渣輝')
  next()
}

//這裏局部調用
// GET http://localhost:3000/
app.get('/', hello, (req, res) => {
  res.send('hello')
})

// GET http://localhost:3000/world
app.get('/world', (req, res) => {
  res.send('world')
})

app.listen(3000, () => {
  console.log('服務啓動成功')
})

4.自定義中間件

const express = require('express');

const app = express();

// 自定義請求日誌中間件
const logger = (req, res, next) => {
    console.log("Request Url:" + req.originalUrl);
    console.log("Request Method:" + req.method);

    console.log("Request Date:" + new Date().toLocaleString());
    // 必須要寫
    next();
}

//自定義中間件,程序延遲執行
const setTimer = (timeout = 5000) => {
    return (req, res, next) => {
        setTimeout(() => {
            //延遲timeout執行
            console.log(`延遲${timeout}秒執行`);
            next();
        }, timeout);
    }
}

//全局調用中間件
app.use(logger);
app.use(setTimer(2000));

app.get('/hello', (req, res, next) => {
    console.log("進入get");
    res.send("結束");
});

app.listen(3000, () => {
    console.log("服務啓動成功");
});

總結一下,在實際開發中,中間件到底處於什麼作用呢?當一個請求發送到服務器後,它的生命週期是 先收到request(請求),然後服務端處理,處理完了以後發送response(響應)回去而這個服務端處理的過程就有文章可做了,想象一下當業務邏輯複雜的時候,爲了明確和便於維護,需要把處理的事情分一下,分配成幾個部分來做,而每個部分就是一箇中間件.

5.app.use方法

use是express註冊中間件的方法,也就是說凡是調用中間件,必須使用use方法,拿上面的第四點代碼中,可看出,使用了app.use方法,註冊了2箇中間件,收到http請求後,先調用logger的中間件,然後做出相應處理,最後通過next()方法,將控制權傳遞給了第二個中間件.然後繼續執行,如果沒有next(),程序將一直掛起,最後無響應

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章