共计 2571 个字符,预计需要花费 7 分钟才能阅读完成。
前言
用过 express
与koa
的同学,对中间件这个概念应该十分相熟了,中间件能够拿到 Request
、Response
对象和 next
函数.
一般来讲中间件有以下作用:
- 执行任何代码
- 对申请与响应拦挡并革新
- 完结
request-response
周期 - 通过
next()
调用下一个中间件 - 如果以后中间件没有完结以后
request-response
周期,必须调用next()
函数,否则申请会处于挂起状态,阻塞整个利用
中间件个别有两种:类中间件 、 函数中间件
类中间件
创立类中间件
应用 @Injectable()
装璜器,并且须要实现 NestMiddleware
接口(use
办法)
// Logger.middleware.ts
import {Injectable, NestMiddleware} from "@nestjs/common";
import {Request, Response} from "express";
@Injectable()
export class LoggerMiddleware implements NestMiddleware {use(req: Request, res: Response, next: () => void) {console.log('logger middleware', `url: ${req.url}`);
next();}
}
应用类中间件
类两头创立完之后,须要在模块中进行挂载,但 @Module
装璜器并没有中间件的相干配置,咱们须要让 module
类实现 NestModule
接口,实现外面 configure 办法来进行挂载
// user.module.ts
import {Module, NestModule} from '@nestjs/common';
import {UserService} from './user.service';
import {UserController} from './user.controller';
import {LoggerMiddleware} from '../middleware/Logger.middleware';
@Module({controllers: [UserController],
providers: [UserService]
})
export class UserModule implements NestModule {configure(consumer) {
consumer
.apply(LoggerMiddleware)
.forRoutes(UserController);
}
}
apply
办法示意挂载的是哪个中间件forRoutes
办法示意对哪个申请门路起作用,这种形式与app.use(path, middleware)
作用是一样,只针对局部门路起作用- 当给
forRoutes
办法传递的是一个controller
控制器时,那么该中间件则对整个控制器下的门路失效
比方这里传递的是 UserController
控制器,那么针对该控制器下的门路都会失效
forRootes
办法还能做更具体的配置,比方能够针对特定的申请办法、申请门路能够应用正则匹配(须要留神的是应用fastify
驱动不能应用)
export class UserModule implements NestModule {configure(consumer) {
consumer
.apply(LoggerMiddleware)
.forRoutes({path: 'user', method: RequestMethod.GET});
}
}
apply
能够同时挂载多个中间件
export class UserModule implements NestModule {configure(consumer) {
consumer
.apply(LoggerMiddleware, aaaMiddleware, ...)
.forRoutes({path: 'user', method: RequestMethod.GET});
}
}
forRoutes
能够应用单个string
门路,多个string
门路,RouteInfo
对象,单个Controller
,多个Controller
export class AppModule implements NestModule {configure(consumer) {
consumer
.apply(LoggerMiddleware, NjMiddleware, ...)
.forRoutes(UserController, NjController, ...);
}
}
exclude
能够用来排除不应用中间件的门路
export class UserModule implements NestModule {configure(consumer) {
consumer
.apply(LoggerMiddleware)
.exclude({path: '/user/a', method: RequestMethod.GET})
.forRoutes(UserController);
}
}
须要留神的是 forRoutes
须要最初调用
函数中间件
这种形式较为简单,应用起来与类中间件统一
创立函数中间件
export function LoggerMiddleware(req: Request, res: Response, next: () => void) {console.log('logger middleware', `url: ${req.url}`);
next();}
应用函数中间件
export class UserModule implements NestModule {configure(consumer) {
consumer
.apply(LoggerMiddleware)
.exclude({path: '/user/a', method: RequestMethod.GET})
.forRoutes(UserController);
}
}
全局中间件
能够间接在入口文件 main.ts
中应用 app.use
来挂载中间件,这样挂载的中间件将全局失效
app.use(LoggerMiddleware) // 日志中间件
中间件其实能够用来实现很多性能,比方:日志零碎、cors 跨域解决、图片防盗等 …
对图片防盗感兴趣的能够看我这篇文章:你不晓得的 HTTP Referer
正文完