NestJs 中間件

https://docs.nestjs.cn/9/middlewares

中間件簡介

  • 中間件是在路由處理程序 之前 調用的函數。 中間件函數可以訪問請求和響應對象,以及應用程序請求響應週期中的 next() 中間件函數。 next() 中間件函數通常由名爲 next 的變量表示。

    圖1

    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();
  }
}

image-20230404145627026

要求我們實現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 執行結束')
  }
}

image-20230404150050041

中間件註冊

註冊方法

在模塊裏面 實現 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})
  }
}

image-20230404152639113

測試

image-20230404152736429

image-20230404152755712

全局中間件

其實全局中間件就是在 根模塊 中實現 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})
  }
}

image-20230404154024816

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