经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » Node.js » 查看文章
【NestJS系列】核心概念:Middleware中间件
来源:cnblogs  作者:前端南玖  时间:2023/8/29 8:47:12  对本文有异议

前言

用过expresskoa的同学,对中间件这个概念应该非常熟悉了,中间件可以拿到RequestResponse对象和next函数.

一般来讲中间件有以下作用:

  • 执行任何代码
  • 对请求与响应拦截并改造
  • 结束request-response周期
  • 通过next()调用下一个中间件
  • 如果当前中间件没有结束当前request-response周期,必须调用next()函数,否则请求会处于挂起状态,阻塞整个应用

中间件一般有两种:类中间件函数中间件

类中间件

创建类中间件

使用@Injectable()装饰器,并且需要实现NestMiddleware接口(use方法)

  1. // Logger.middleware.ts
  2. import { Injectable, NestMiddleware } from "@nestjs/common";
  3. import { Request, Response } from "express";
  4. @Injectable()
  5. export class LoggerMiddleware implements NestMiddleware {
  6. use(req: Request, res: Response, next: () => void) {
  7. console.log('logger middleware', `url: ${req.url}`);
  8. next();
  9. }
  10. }

使用类中间件

类中间创建完之后,需要在模块中进行挂载,但@Module装饰器并没有中间件的相关配置,我们需要让module类实现NestModule接口,实现里面configure方法来进行挂载

  1. // user.module.ts
  2. import { Module, NestModule } from '@nestjs/common';
  3. import { UserService } from './user.service';
  4. import { UserController } from './user.controller';
  5. import { LoggerMiddleware } from '../middleware/Logger.middleware';
  6. @Module({
  7. controllers: [UserController],
  8. providers: [UserService]
  9. })
  10. export class UserModule implements NestModule {
  11. configure(consumer) {
  12. consumer
  13. .apply(LoggerMiddleware)
  14. .forRoutes(UserController);
  15. }
  16. }
  • apply方法表示挂载的是哪个中间件
  • forRoutes方法表示对哪个请求路径起作用,这种方式与app.use(path, middleware)作用是一样,只针对部分路径起作用
  • 当给forRoutes方法传递的是一个controller控制器时,那么该中间件则对整个控制器下的路径生效

比如这里传递的是UserController控制器,那么针对该控制器下的路径都会生效

  • forRootes方法还能做更详细的配置,比如可以针对特定的请求方法、请求路径可以使用正则匹配(需要注意的是使用fastify驱动不能使用)
  1. export class UserModule implements NestModule {
  2. configure(consumer) {
  3. consumer
  4. .apply(LoggerMiddleware)
  5. .forRoutes({ path: 'user', method: RequestMethod.GET});
  6. }
  7. }
  • apply可以同时挂载多个中间件
  1. export class UserModule implements NestModule {
  2. configure(consumer) {
  3. consumer
  4. .apply(LoggerMiddleware, aaaMiddleware, ...)
  5. .forRoutes({ path: 'user', method: RequestMethod.GET});
  6. }
  7. }
  • forRoutes可以使用单个string路径,多个string路径,RouteInfo对象,单个Controller,多个Controller
  1. export class AppModule implements NestModule {
  2. configure(consumer) {
  3. consumer
  4. .apply(LoggerMiddleware, NjMiddleware, ...)
  5. .forRoutes(UserController, NjController, ...);
  6. }
  7. }
  • exclude可以用来排除不使用中间件的路径
  1. export class UserModule implements NestModule {
  2. configure(consumer) {
  3. consumer
  4. .apply(LoggerMiddleware)
  5. .exclude({ path: '/user/a', method: RequestMethod.GET})
  6. .forRoutes(UserController);
  7. }
  8. }

需要注意的是forRoutes需要最后调用

函数中间件

这种方式较为简单,使用起来与类中间件一致

创建函数中间件

  1. export function LoggerMiddleware(req: Request, res: Response, next: () => void) {
  2. console.log('logger middleware', `url: ${req.url}`);
  3. next();
  4. }

使用函数中间件

  1. export class UserModule implements NestModule {
  2. configure(consumer) {
  3. consumer
  4. .apply(LoggerMiddleware)
  5. .exclude({ path: '/user/a', method: RequestMethod.GET})
  6. .forRoutes(UserController);
  7. }
  8. }

全局中间件

可以直接在入口文件main.ts中使用app.use来挂载中间件,这样挂载的中间件将全局生效

  1. app.use(LoggerMiddleware) // 日志中间件

中间件其实可以用来实现很多功能,比如:日志系统、cors跨域处理、图片防盗等...

对图片防盗感兴趣的可以看我这篇文章:你不知道的 HTTP Referer

原文链接:https://www.cnblogs.com/songyao666/p/17663268.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号