一、简介
- 中间件 - 官方文档。
- 中间件是在路由处理程序 之前 调用的函数。 中间件函数可以访问请求和响应对象,以及应用程序请求响应周期中的
next()
中间件函数。next()
中间件函数通常由名为next
的变量表示。 - 也就跟前端路由守卫一样,做个访问拦截处理,但是它这个可以支持读个中间件。
二、class
中间件
- 通过指令自动创建,也可以手动创建
$ nest g mi logger
module.ts
文件中进行注册中间件,在app.module.ts
中举例,如果想在其他module.ts
中也同理。
import { MiddlewareConsumer, Module, NestModule, RequestMethod } from '@nestjs/common'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { UserModule } from './user/user.module'; import { LoggerMiddleware } from './logger.middleware'; import { LoginModule } from './login/login.module'; import { LoginController } from './login/login.controller'; @Module({ imports: [UserModule, LoginModule], controllers: [AppController], providers: [AppService], }) export class AppModule implements NestModule { configure(consumer: MiddlewareConsumer) { // 监听 login 访问 consumer.apply(LoggerMiddleware).forRoutes('login') // 监听 login 访问 // consumer.apply(LoggerMiddleware).forRoutes('/login') // 监听 LoginController 中所有路由访问 // consumer.apply(LoggerMiddleware).forRoutes(LoginController) // 监听指定路由 /user/dzm 访问 // consumer.apply(LoggerMiddleware).forRoutes({ path: '/user/dzm', method: RequestMethod.GET }) // 监听 LoginController 中所有路由访问,并过滤掉 /login 不进行监听,只监听其他路由访问 // consumer.apply(LoggerMiddleware).exclude('/login').forRoutes(LoginController) // 这种就是过滤掉 /user/123 这种路由,路由参数是可变的这种 // consumer.apply(LoggerMiddleware).exclude('/user/(.*)').forRoutes(UserController) } }
三、函数中间件
- 文件可以手动创建,也可以通过指令创建
import { Injectable, NestMiddleware } from '@nestjs/common'; import { NextFunction } from 'express'; @Injectable() export class LoggerMiddleware implements NestMiddleware { use(req: Request, res: Response, next: NextFunction) { console.log('调用了拦截1') next(); } } // 函数中间件,直接导出这个使用注册即可 export function logger(req, res, next) { console.log('调用了拦截2'); next(); };
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { UserModule } from './user/user.module'; import { logger } from './logger.middleware'; import { LoginModule } from './login/login.module'; @Module({ imports: [UserModule, LoginModule], controllers: [AppController], providers: [AppService], }) export class AppModule implements NestModule { configure(consumer: MiddlewareConsumer) { // 监听 login 访问,注册 logger 中间件 consumer.apply(logger).forRoutes('login') // 其他的注册方式都支持... } }
四、多个中间件
- 多个中间件,逗号隔开就行
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { UserModule } from './user/user.module'; import { LoggerMiddleware, logger } from './logger.middleware'; import { LoginModule } from './login/login.module'; @Module({ imports: [UserModule, LoginModule], controllers: [AppController], providers: [AppService], }) export class AppModule implements NestModule { configure(consumer: MiddlewareConsumer) { // 监听 login 访问 consumer.apply(LoggerMiddleware, logger).forRoutes('login') } }
五、全局中间件
- 全局中间件只需要在
main.ts
中注册即可,而且只支持函数中间件。
import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { LoggerMiddleware, logger } from './logger.middleware'; async function bootstrap() { const app = await NestFactory.create(AppModule); // ❎ 这里不能用 class 中间件 // app.use(LoggerMiddleware) // ✅ 全局中间件只能使用 函数中间件 app.use(logger) await app.listen(3000); } bootstrap();