Node.js使用Middleware中間件教程詳解
中間件
中間件是一個(gè)在路由處理程序之前被調(diào)用的函數(shù)。中間件函數(shù)可以訪問(wèn)請(qǐng)求和響應(yīng)對(duì)象,以及應(yīng)用程序的請(qǐng)求-響應(yīng)周期中的next()
中間件函數(shù)。下一個(gè)中間件函數(shù)通常由一個(gè)名為next
的變量來(lái)表示。
Nest 中間件在默認(rèn)情況下等同于Express
中間件。下面是來(lái)自官方 express 文檔的描述,描述了中間件的能力。
中間件函數(shù)可以執(zhí)行以下任務(wù):
1、執(zhí)行任何代碼。
2、對(duì)請(qǐng)求和響應(yīng)對(duì)象進(jìn)行更改。
3、結(jié)束請(qǐng)求-響應(yīng)周期。
4、調(diào)用堆棧中的下一個(gè)中間件函數(shù)。
5、如果當(dāng)前中間件函數(shù)沒(méi)有結(jié)束請(qǐng)求-響應(yīng)周期,則必須調(diào)用`next()`將控制權(quán)傳遞給下一個(gè)中間件函數(shù)。
否則,請(qǐng)求將保持掛起狀態(tài)。
你可以在一個(gè)函數(shù)中實(shí)現(xiàn)自定義 Nest 中間件,或者在一個(gè)帶有@Injectable()
裝飾器的類中實(shí)現(xiàn)。類應(yīng)該實(shí)現(xiàn)NestMiddleware
接口,而函數(shù)則沒(méi)有任何特殊要求。讓我們先用類的方法實(shí)現(xiàn)一個(gè)簡(jiǎ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)系。像往常一樣,這是通過(guò)構(gòu)造函數(shù)完成的。
應(yīng)用中間件
在@Module()
裝飾器中沒(méi)有中間件的參數(shù)位置。所以,我們使用模塊類的configure()
方法來(lái)設(shè)置它們。包含中間件的模塊必須實(shí)現(xiàn)NestModule
接口。讓我們?cè)?code>AppModule級(jí)別設(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
。在配置中間件時(shí),我們還可以通過(guò)向forRoutes()
方法傳遞一個(gè)包含路由路徑和請(qǐng)求方法的對(duì)象來(lái)進(jìn)一步將中間件限制在一個(gè)特定的請(qǐng)求方法上。在下面的例子中,注意到我們導(dǎo)入了RequestMethod
枚舉來(lái)引用所需的請(qǐng)求方法類型。
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 進(jìn)行異步操作(例如,你可以在 configure()方法主體內(nèi)等待一個(gè)異步操作的完成)
警告
當(dāng)使用Express
適配器時(shí),NestJS
應(yīng)用程序?qū)⒛J(rèn)從包的body-parser
注冊(cè) json 和 urlencoded。這意味著如果你想通過(guò)MiddlewareConsumer
定制該中間件,你需要在用NestFactory.create()
創(chuàng)建應(yīng)用程序時(shí)將bodyParser
標(biāo)志設(shè)置為false
,從而關(guān)閉全局中間件。
路由通配符
也支持基于模式的路由。例如,星號(hào)被用作通配符,將匹配任何字符的組合:
forRoutes({ path: "ab*cd", method: RequestMethod.ALL });
'ab*cd'
路由路徑將匹配 abcd、ab_cd、abecd,等等。字符"?“、”+“、”*“和”()"可以在路徑中使用,它們是對(duì)應(yīng)于正則表達(dá)式的子集。連字符(-)和點(diǎn)(.)可以通過(guò)基于字符串的路徑進(jìn)行字面解釋。
中間件消費(fèi)者
MiddlewareConsumer
是一個(gè)輔助類。它提供了幾種內(nèi)置方法來(lái)管理中間件。所有這些都可以簡(jiǎn)單地以Fluent styple。forRoutes()
方法可以采用單個(gè)字符串、多個(gè)字符串、RouteInfo
對(duì)象、一個(gè)控制器類甚至多個(gè)控制器類。在大多數(shù)情況下,你可能只會(huì)傳遞一個(gè)以逗號(hào)分隔的控制器列表。下面是單個(gè)控制器的示例:
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()
方法可以使用單個(gè)中間件,也可以使用多個(gè)參數(shù)來(lái)指定多個(gè)多個(gè)中間件。
路由排除
有時(shí)我們希望從應(yīng)用中間件中排除某些路由。我們可以使用 exclude()
方法輕松排除某些路由。此方法可以采用單個(gè)字符串、多個(gè)字符串或標(biāo)識(shí)要排除的路由的 RouteInfo
對(duì)象,如下所示:
consumer .apply(LoggerMiddleware) .exclude( { path: "cats", method: RequestMethod.GET }, { path: "cats", method: RequestMethod.POST }, "cats/(.*)" ) .forRoutes(CatsController);
exclude()
方法支持使用正則表達(dá)式包路徑的通配符參數(shù)。
在上面的例子中,LoggerMiddleware
將被綁定到 CatsController
中定義的所有路由,除了傳遞給 exclude()
方法的三個(gè)路由。
函數(shù)式中間件
我們一直在使用的LoggerMiddleware
類非常簡(jiǎn)單。它沒(méi)有成員,沒(méi)有其他方法,也沒(méi)有依賴項(xiàng)。為什么我們不能在一個(gè)簡(jiǎn)單的函數(shù)而不是類中定義它?事實(shí)上,我們可以。這種類型的中間件稱為函數(shù)式間件。讓我們將LoggerMiddleware
中間件從基于類的中間件轉(zhuǎn)換為函數(shù)式間件,以說(shuō)明其中的區(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);
只要中間件不需要任何依賴項(xiàng),請(qǐng)考慮使用更簡(jiǎn)單的 函數(shù)式中間件
替代方法。
多個(gè)中間件
如上所述,為了綁定多個(gè)按順序執(zhí)行的中間件,只需在 ‘apply()’ 方法中提供一個(gè)逗號(hào)分隔的列表:
consumer.apply(cors(), helmet(), logger).forRoutes(CatsController);
全局中間件
如果我們想一次將中間件綁定到每個(gè)注冊(cè)的路由,我們可以使用INestApplication
實(shí)例提供的 use()
方法:
const app = await NestFactory.create(AppModule); app.use(logger); await app.listen(3000);
無(wú)法訪問(wèn)全局中間件中的 DI 容器。當(dāng)使用app.use()
時(shí),您可以使用[函數(shù)式中間件](中間件#functional-middleware)代替?;蛘?,您可以使用類中間件并將其與AppModule
或任何其他模塊)中的.forRoutes(”*“)
一起使用。
到此這篇關(guān)于Node.js使用Middleware中間件教程詳解的文章就介紹到這了,更多相關(guān)Node.js Middleware內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
NodeJS中利用Promise來(lái)封裝異步函數(shù)
這篇文章主要介紹了NodeJS中利用Promise來(lái)封裝異步函數(shù),使用統(tǒng)一的鏈?zhǔn)紸PI來(lái)擺脫多重回調(diào)的噩夢(mèng),非常的實(shí)用的小技能,希望小伙伴們能夠喜歡2015-02-02Node.js websocket使用socket.io庫(kù)實(shí)現(xiàn)實(shí)時(shí)聊天室
這篇文章主要為大家詳細(xì)介紹了Node.js websocket使用socket.io庫(kù)實(shí)現(xiàn)實(shí)時(shí)聊天室,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-02-02NodeJS模塊與ES6模塊系統(tǒng)語(yǔ)法及注意點(diǎn)詳解
這篇文章主要給大家介紹了關(guān)于NodeJS模塊與ES6模塊系統(tǒng)語(yǔ)法及注意點(diǎn)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-01-01node.js+postman實(shí)現(xiàn)模擬HTTP服務(wù)器與客戶端交互
本文主要介紹了node.js+postman實(shí)現(xiàn)模擬HTTP服務(wù)器與客戶端交互,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-07-07Node.js腳本提取OPML文件信息實(shí)現(xiàn)示例詳解
這篇文章主要為大家介紹了Node.js腳本提取OPML文件信息,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09nodejs基礎(chǔ)之多進(jìn)程實(shí)例詳解
這篇文章主要介紹了nodejs基礎(chǔ)之多進(jìn)程,結(jié)合實(shí)例形式分析了nodejs多進(jìn)程的概念、原理、相關(guān)函數(shù)使用方法及操作注意事項(xiàng),需要的朋友可以參考下2018-12-12