中间件是在路由处理程序之前调用的函数。在中间件中可以访问请求和响应对象,也可以访问next()函数,当中间件处理完毕后必须调用next()将控制权交给下一个中间件,否则,请求将会被挂起。中间件的处理如下图:
1.自定义Middleware
自定义Middleware只需要做两件事,第一是使用@Injectable装饰器将中间件注入到IOC容器,第二步是实现NestMiddleware接口并重写该接口的use方法,use方法接收请求对象、响应对象、next函数3个参数,注意必须调用next()将控制权交给下一个中间件,否则请求将会被挂起。未使用@Injectable装饰器修饰中间件仍能正常访问。
/*** src/common/middleware** 自定义middleware只需两步操作,第一使用@Injectable装饰器将中间件注入到IOC容器,* 第二步是实现NestMiddleware接口重写该接口的use方法。*/import { Injectable, NestMiddleware } from '@nestjs/common';@Injectable()export class LoggerMiddleware implements NestMiddleware {/** req 为请求对象,res为响应对象,next()用于调用下一个中间件*/use(req: any, res: any, next: () => void) {console.log('我是Logger Middleware');next();}}
在module中使用中间件,使用中间件需要实现NestModule并重写configure函数,configure函数接收一个中间件消费者对象,通过调用该对象的apply可以使用Middleware,也可以使用exclude()排除不需要被中间件处理的请求,也可以使用forRoutes对包含某个路由前缀进行处理。
//app.module.tsimport {Module,NestModule,MiddlewareConsumer,RequestMethod,} from '@nestjs/common';import { AppController } from './app.controller';import { AppService } from './app.service';import { LoggerMiddleware } from './common/middleware/logger.middleware';@Module({imports: [],controllers: [AppController],providers: [AppService],})export class AppModule implements NestModule {configure(consumer: MiddlewareConsumer) {/*** exclude用于排除请求,例如下面例子中表示排除路径为/getUser并且请求类型为get的请求。* forRoutes表示中间件只应用于请求url前缀为app的请求。* apply()中可以传入多个中间件,以逗号隔开*/consumer.apply(LoggerMiddleware).exclude({ path: '/getUser', method: RequestMethod.GET }).forRoutes('app');}}
//app.controller.tsimport { Controller, Get } from '@nestjs/common';import { AppService } from './app.service';@Controller('/app')export class AppController {constructor(private readonly appService: AppService) {}//当访问localhost:3000/app/hello时请求会被中间件拦截到@Get('/hello')getHello(): string {return this.appService.getHello();}}
2.函数Middleware
import { Request, Response, NextFunction } from 'express';/** req 为请求对象,res为响应对象,next()用于调用下一个中间件*/export default function (req: Request, res: Response, next: NextFunction) {console.log('我是函数中间件....');next();}
2.使用全局中间件
import FuncMiddleware from './common/middleware/func.middleware';const app = await NestFactory.create(AppModule);//使用create()创建的INestApplication实例,通过该实例的use()调用中间件,注意use()调用的中间件必须是函数中间件app.use(logger);await app.listen(3000)
