前言
用过express
与koa
的同学,对中间件这个概念应该十分相熟了,中间件能够拿到Request
、Response
对象和next
函数.
一般来讲中间件有以下作用:
- 执行任何代码
- 对申请与响应拦挡并革新
- 完结
request-response
周期 - 通过
next()
调用下一个中间件 - 如果以后中间件没有完结以后
request-response
周期,必须调用next()
函数,否则申请会处于挂起状态,阻塞整个利用
中间件个别有两种:类中间件、函数中间件
类中间件
创立类中间件
应用@Injectable()
装璜器,并且须要实现NestMiddleware
接口(use
办法)
// Logger.middleware.tsimport { 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.tsimport { 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