https://docs.nestjs.cn/9/middlewares
中間件簡介
-
中間件是在路由處理程序 之前 調用的函數。 中間件函數可以訪問請求和響應對象,以及應用程序請求響應週期中的
next()
中間件函數。next()
中間件函數通常由名爲next
的變量表示。Nest 中間件實際上等價於 express 中間件。 下面是Express官方文檔中所述的中間件功能:
中間件函數可以執行以下任務:
- 執行任何代碼。
- 對請求和響應對象進行更改。
- 結束請求-響應週期。
- 調用堆棧中的下一個中間件函數。
- 如果當前的中間件函數沒有結束請求-響應週期, 它必須調用
next()
將控制傳遞給下一個中間件函數。否則, 請求將被掛起。
您可以在函數中或在具有
@Injectable()
裝飾器的類中實現自定義Nest
中間件。 這個類應該實現NestMiddleware
接口, 而函數沒有任何特殊的要求。 讓我們首先使用類方法實現一個簡單的中間件功能。
創建中間件
新建 middlewares
文件夾,在此路徑下執行下面的命令來創建
nest g mi Login
生成的主要代碼
login.middleware.ts
import { Injectable, NestMiddleware } from '@nestjs/common';
@Injectable()
export class LoginMiddleware implements NestMiddleware {
use(req: any, res: any, next: () => void) {
next();
}
}
要求我們實現use 函數 返回 req res next 參數 如果不調用next 程序將被掛起
實現use 函數
import { Injectable, NestMiddleware } from '@nestjs/common';
@Injectable()
export class LoginMiddleware implements NestMiddleware {
use(req: any, res: any, next: () => void) {
// 假設中間件攔截步驟
console.log('LoginMiddleware 登錄攔截中間件,攔截了:', req.query);
// 放行
next();
console.log('LoginMiddleware 執行結束')
}
}
中間件註冊
註冊方法
在模塊裏面 實現 configure 返回一個消費者 consumer 通過 apply 註冊中間件 通過forRoutes 指定 Controller 路由
模塊中間件
實現
在對應模塊實現
例:p 模塊
import { MiddlewareConsumer, Module, NestModule, RequestMethod } from '@nestjs/common';
import { PService } from './p.service';
import { PController } from './p.controller';
import { LoginMiddleware } from 'src/middlewares/login/login.middleware';
@Module({
controllers: [PController],
providers: [PService]
})
/**
* 中間件不能在 @Module() 裝飾器中列出。
* 我們必須使用模塊類的 configure() 方法來設置它們。
* 包含中間件的模塊必須實現 NestModule 接口。
* 我們將 LoggerMiddleware 設置在 ApplicationModule 層上。
*/
export class PModule implements NestModule{
// 在模塊裏面 實現 configure 返回一個消費者 consumer
// 通過 apply 註冊中間件 通過forRoutes 指定 Controller 路由
configure (consumer:MiddlewareConsumer) {
// 攔截 p 模塊
consumer.apply(LoginMiddleware).forRoutes('p')
// consumer.apply(LoginMiddleware).forRoutes(PController)
// 攔截 p 模塊的get方法
// consumer.apply(LoginMiddleware).forRoutes({path: 'p', method:RequestMethod.GET})
}
}
測試
全局中間件
其實全局中間件就是在 根模塊 中實現 configure 註冊,所謂根模塊就是 app.module.ts
主要代碼
export class AppModule {
// 在模塊裏面 實現 configure 返回一個消費者 consumer
// 通過 apply 註冊中間件 通過forRoutes 指定 Controller 路由
configure (consumer:MiddlewareConsumer) {
// 攔截 p 模塊
consumer.apply(LoginMiddleware).forRoutes('*')
// consumer.apply(LoginMiddleware).forRoutes(PController)
// 攔截 p 模塊的get方法
// consumer.apply(LoginMiddleware).forRoutes({path: 'p', method:RequestMethod.GET})
}
}