NestJs 中间件
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})
}
}