一、关于 NestJS 中间件
- 通俗的讲:中间件就是匹配路由之前或者匹配路由完成做的一系列的操作。中间件中如果想往下 匹配的话,那么需要写 next()
- NestJS 的中间件实际上等价于 express 中间件。 下面是 Express 官方文档中所述的中间件功能:
NestJS 中间件可以是一个函数,也可以是一个带有 @Injectable() 装饰器的类
// 中间件函数可以执行以下任务:
执行任何代码。
对请求和响应对象进行更改。
结束请求-响应周期。
调用堆栈中的下一个中间件函数。
如果当前的中间件函数没有结束请求-响应周期, 它必须调用 next() 将控制传递给下一个中间 件函数。否则, 请求将被挂起。
二、NestJS 中创建使用中间件
https://docs.nestjs.cn/8/middlewares
1、创建中间件
```typescript nest g middleware middleware/init
// 创建完成生成下面的代码 import { Injectable, NestMiddleware } from ‘@nestjs/common’; @Injectable() export class InitMiddleware implements NestMiddleware { use(req: any, res: any, next: () => void) { console.log(‘init中间件’) next(); } }
<a name="Rc61H"></a>
##### 2、配置中间件,中间件不能在 @Module() 装饰器中列出。我们必须使用模块类的 configure() 方法来设置它们。包含中间件的模块必须实现 NestModule 接口。我们将 LoggerMiddleware 设置在 ApplicationModule 层上
```typescript
// 在 src/app.module.ts 中继承 NestModule 然后配置中间件
import { Module, NestModule, MiddlewareConsumer, RequestMethod } from '@nestjs/common';
import { InitMiddleware } from './middleware/init.middleware'; // 引入中间件
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer.apply(InitMiddleware)
// .forRoutes('*'); // 表示匹配所有的路由
// .forRoutes('user'); // 表示只有访问user路由的时候才走这个中间件
// .forRoutes({ path: 'user', method: RequestMethod.All }); // 路由中的所有方法匹配中间件
// .forRoutes({ path: 'user', method: RequestMethod.GET }); // 路由中的GET方法匹配中间件
.forRoutes( // user和news路由匹配中间件
{ path: 'user', method: RequestMethod.GET },
{ path: 'news', method: RequestMethod.All },
);
}
}
三、多个中间件
// 下面表示所有路由都匹配 InitMiddleware 中间件,user不仅匹配 InitMiddleware 中间件,还匹配 UserMiddleware 中间件
consumer.apply(InitMiddleware).forRoutes('*').apply(UserMiddleware).forRoutes('user')
// 下面表示 user 和 news 路由都匹配 NewsMiddleware 和 NewsMiddleware 中间件
consumer.apply(UserMiddleware, NewsMiddleware).forRoutes(
{ path: 'user', method: RequestMethod.GET },
{ path: 'news', method: RequestMethod.GET },
)
四、函数式中间件 - NestJS不常用
function logger(req, res, next) {
console.log('函数式中间件');
next();
};
// 使用函数式中间件和正常使用一样
consumer.apply(logger).forRoutes('*');
五、全局中间件
// src/main.ts 全局中间件只能引入函数式中间件
import { logger } from './middleware/logger.middleware'; // 引入中间件
app.use(logger)