Node.js使用Middleware中間件教程詳解
中間件
中間件是一個在路由處理程序之前被調(diào)用的函數(shù)。中間件函數(shù)可以訪問請求和響應(yīng)對象,以及應(yīng)用程序的請求-響應(yīng)周期中的next()中間件函數(shù)。下一個中間件函數(shù)通常由一個名為next的變量來表示。

Nest 中間件在默認(rèn)情況下等同于Express中間件。下面是來自官方 express 文檔的描述,描述了中間件的能力。
中間件函數(shù)可以執(zhí)行以下任務(wù):
1、執(zhí)行任何代碼。
2、對請求和響應(yīng)對象進行更改。
3、結(jié)束請求-響應(yīng)周期。
4、調(diào)用堆棧中的下一個中間件函數(shù)。
5、如果當(dāng)前中間件函數(shù)沒有結(jié)束請求-響應(yīng)周期,則必須調(diào)用`next()`將控制權(quán)傳遞給下一個中間件函數(shù)。
否則,請求將保持掛起狀態(tài)。
你可以在一個函數(shù)中實現(xiàn)自定義 Nest 中間件,或者在一個帶有@Injectable()裝飾器的類中實現(xiàn)。類應(yīng)該實現(xiàn)NestMiddleware接口,而函數(shù)則沒有任何特殊要求。讓我們先用類的方法實現(xiàn)一個簡單的中間件功能。
import { Injectable, NestMiddleware } from "@nestjs/common";
import { Request, Response, NextFunction } from "express";
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
console.log("Request...");
next();
}
}
依賴注入
Nest 中間件完全支持依賴性注入。就像提供者和控制器一樣,它們能夠注入同一模塊內(nèi)可用的依賴關(guān)系。像往常一樣,這是通過構(gòu)造函數(shù)完成的。
應(yīng)用中間件
在@Module()裝飾器中沒有中間件的參數(shù)位置。所以,我們使用模塊類的configure()方法來設(shè)置它們。包含中間件的模塊必須實現(xiàn)NestModule接口。讓我們在AppModule級別設(shè)置LoggerMiddleware。
import { Module, NestModule, MiddlewareConsumer } from "@nestjs/common";
import { LoggerMiddleware } from "./common/middleware/logger.middleware";
import { CatsModule } from "./cats/cats.module";
@Module({
imports: [CatsModule],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer.apply(LoggerMiddleware).forRoutes("cats");
}
}
在上面的例子中,我們已經(jīng)為之前在CatsController中定義的/cats路由處理程序設(shè)置了LoggerMiddleware。在配置中間件時,我們還可以通過向forRoutes()方法傳遞一個包含路由路徑和請求方法的對象來進一步將中間件限制在一個特定的請求方法上。在下面的例子中,注意到我們導(dǎo)入了RequestMethod枚舉來引用所需的請求方法類型。
import {
Module,
NestModule,
RequestMethod,
MiddlewareConsumer,
} from "@nestjs/common";
import { LoggerMiddleware } from "./common/middleware/logger.middleware";
import { CatsModule } from "./cats/cats.module";
@Module({
imports: [CatsModule],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(LoggerMiddleware)
.forRoutes({ path: "cats", method: RequestMethod.GET });
}
}
configure()方法可以使用 async/await 進行異步操作(例如,你可以在 configure()方法主體內(nèi)等待一個異步操作的完成)
警告
當(dāng)使用Express適配器時,NestJS應(yīng)用程序?qū)⒛J(rèn)從包的body-parser注冊 json 和 urlencoded。這意味著如果你想通過MiddlewareConsumer定制該中間件,你需要在用NestFactory.create()創(chuàng)建應(yīng)用程序時將bodyParser標(biāo)志設(shè)置為false,從而關(guān)閉全局中間件。
路由通配符
也支持基于模式的路由。例如,星號被用作通配符,將匹配任何字符的組合:
forRoutes({ path: "ab*cd", method: RequestMethod.ALL });'ab*cd' 路由路徑將匹配 abcd、ab_cd、abecd,等等。字符"?“、”+“、”*“和”()"可以在路徑中使用,它們是對應(yīng)于正則表達式的子集。連字符(-)和點(.)可以通過基于字符串的路徑進行字面解釋。
中間件消費者
MiddlewareConsumer是一個輔助類。它提供了幾種內(nèi)置方法來管理中間件。所有這些都可以簡單地以Fluent styple。forRoutes()方法可以采用單個字符串、多個字符串、RouteInfo對象、一個控制器類甚至多個控制器類。在大多數(shù)情況下,你可能只會傳遞一個以逗號分隔的控制器列表。下面是單個控制器的示例:
import { Module, NestModule, MiddlewareConsumer } from "@nestjs/common";
import { LoggerMiddleware } from "./common/middleware/logger.middleware";
import { CatsModule } from "./cats/cats.module";
import { CatsController } from "./cats/cats.controller";
@Module({
imports: [CatsModule],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer.apply(LoggerMiddleware).forRoutes(CatsController);
}
}
該 apply() 方法可以使用單個中間件,也可以使用多個參數(shù)來指定多個多個中間件。
路由排除
有時我們希望從應(yīng)用中間件中排除某些路由。我們可以使用 exclude() 方法輕松排除某些路由。此方法可以采用單個字符串、多個字符串或標(biāo)識要排除的路由的 RouteInfo 對象,如下所示:
consumer
.apply(LoggerMiddleware)
.exclude(
{ path: "cats", method: RequestMethod.GET },
{ path: "cats", method: RequestMethod.POST },
"cats/(.*)"
)
.forRoutes(CatsController);
exclude() 方法支持使用正則表達式包路徑的通配符參數(shù)。
在上面的例子中,LoggerMiddleware將被綁定到 CatsController 中定義的所有路由,除了傳遞給 exclude() 方法的三個路由。
函數(shù)式中間件
我們一直在使用的LoggerMiddleware類非常簡單。它沒有成員,沒有其他方法,也沒有依賴項。為什么我們不能在一個簡單的函數(shù)而不是類中定義它?事實上,我們可以。這種類型的中間件稱為函數(shù)式間件。讓我們將LoggerMiddleware中間件從基于類的中間件轉(zhuǎn)換為函數(shù)式間件,以說明其中的區(qū)別:
import { Request, Response, NextFunction } from "express";
export function logger(req: Request, res: Response, next: NextFunction) {
console.log(`Request...`);
next();
}
在AppModule中使用它:
consumer.apply(logger).forRoutes(CatsController);
只要中間件不需要任何依賴項,請考慮使用更簡單的 函數(shù)式中間件 替代方法。
多個中間件
如上所述,為了綁定多個按順序執(zhí)行的中間件,只需在 ‘apply()’ 方法中提供一個逗號分隔的列表:
consumer.apply(cors(), helmet(), logger).forRoutes(CatsController);
全局中間件
如果我們想一次將中間件綁定到每個注冊的路由,我們可以使用INestApplication 實例提供的 use()方法:
const app = await NestFactory.create(AppModule); app.use(logger); await app.listen(3000);
無法訪問全局中間件中的 DI 容器。當(dāng)使用app.use() 時,您可以使用[函數(shù)式中間件](中間件#functional-middleware)代替?;蛘?,您可以使用類中間件并將其與AppModule或任何其他模塊)中的.forRoutes(”*“)一起使用。
到此這篇關(guān)于Node.js使用Middleware中間件教程詳解的文章就介紹到這了,更多相關(guān)Node.js Middleware內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Node.js中文件操作模塊File System的詳細介紹
FileSystem模塊是類似UNIX(POSIX)標(biāo)準(zhǔn)的文件操作API,用于操作文件系統(tǒng)——讀寫目錄、讀寫文件——Node.js底層使用C程序來實現(xiàn),這些功能是客戶端JS所不具備的。下面這篇文章就給大家詳細介紹了Node.js中的文件操作模塊File System,有需要的朋友們可以參考借鑒。2017-01-01
node.js應(yīng)用后臺守護進程管理器Forever安裝和使用實例
這篇文章主要介紹了node.js應(yīng)用后臺守護進程管理器Forever安裝和使用實例,forever可以看做是一個nodejs的守護進程,能夠啟動,停止,重啟我們的app應(yīng)用,需要的朋友可以參考下2014-06-06
DevEco?Studio設(shè)置Nodejs提示路徑只能包含英文、數(shù)字、下劃線等解決辦法
這篇文章主要給大家介紹了關(guān)于DevEco?Studio設(shè)置Nodejs提示路徑只能包含英文、數(shù)字、下劃線等的解決辦法,文中通過圖文介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考借鑒價值,需要的朋友可以參考下2024-01-01
nodejs個人博客開發(fā)第四步 數(shù)據(jù)模型
這篇文章主要為大家詳細介紹了nodejs個人博客開發(fā)的數(shù)據(jù)模型,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-04-04
Node.js中MongoDB插入數(shù)據(jù)的實現(xiàn)方法
在Node.js中,可以使用MongoDB原生驅(qū)動或Mongoose庫來連接和操作MongoDB數(shù)據(jù)庫,本文就來介紹一下Node.js中MongoDB插入數(shù)據(jù)的實現(xiàn)方法,感興趣的可以了解一下2023-12-12
npm報錯"A?complete?log?of?this?run?can?be?found?
這篇文章主要給大家介紹了關(guān)于npm報錯"A?complete?log?of?this?run?can?be?found?in:"的解決辦法,文中通過實例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2023-04-04

