文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Node.js使用Middleware中间件教程详解

2023-05-15 17:53

关注

中间件

中间件是一个在路由处理程序之前被调用的函数。中间件函数可以访问请求和响应对象,以及应用程序的请求-响应周期中的next()中间件函数。下一个中间件函数通常由一个名为next的变量来表示。

Nest 中间件在默认情况下等同于Express中间件。下面是来自官方 express 文档的描述,描述了中间件的能力。

中间件函数可以执行以下任务:
1、执行任何代码。
2、对请求和响应对象进行更改。
3、结束请求-响应周期。
4、调用堆栈中的下一个中间件函数。
5、如果当前中间件函数没有结束请求-响应周期,则必须调用`next()`将控制权传递给下一个中间件函数。
   否则,请求将保持挂起状态。

你可以在一个函数中实现自定义 Nest 中间件,或者在一个带有@Injectable()装饰器的类中实现。类应该实现NestMiddleware接口,而函数则没有任何特殊要求。让我们先用类的方法实现一个简单的中间件功能。

import { Injectable, NestMiddleware } from "@nestjs/common";
import { Request, Response, NextFunction } from "express";
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  use(req: Request, res: Response, next: NextFunction) {
    console.log("Request...");
    next();
  }
}

依赖注入

Nest 中间件完全支持依赖性注入。就像提供者和控制器一样,它们能够注入同一模块内可用的依赖关系。像往常一样,这是通过构造函数完成的。

应用中间件

@Module()装饰器中没有中间件的参数位置。所以,我们使用模块类的configure()方法来设置它们。包含中间件的模块必须实现NestModule接口。让我们在AppModule级别设置LoggerMiddleware

import { Module, NestModule, MiddlewareConsumer } from "@nestjs/common";
import { LoggerMiddleware } from "./common/middleware/logger.middleware";
import { CatsModule } from "./cats/cats.module";
@Module({
  imports: [CatsModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(LoggerMiddleware).forRoutes("cats");
  }
}

在上面的例子中,我们已经为之前在CatsController中定义的/cats路由处理程序设置了LoggerMiddleware。在配置中间件时,我们还可以通过向forRoutes()方法传递一个包含路由路径和请求方法的对象来进一步将中间件限制在一个特定的请求方法上。在下面的例子中,注意到我们导入了RequestMethod枚举来引用所需的请求方法类型。

import {
  Module,
  NestModule,
  RequestMethod,
  MiddlewareConsumer,
} from "@nestjs/common";
import { LoggerMiddleware } from "./common/middleware/logger.middleware";
import { CatsModule } from "./cats/cats.module";
@Module({
  imports: [CatsModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes({ path: "cats", method: RequestMethod.GET });
  }
}

configure()方法可以使用 async/await 进行异步操作(例如,你可以在 configure()方法主体内等待一个异步操作的完成)

警告

当使用Express适配器时,NestJS应用程序将默认从包的body-parser注册 json 和 urlencoded。这意味着如果你想通过MiddlewareConsumer定制该中间件,你需要在用NestFactory.create()创建应用程序时将bodyParser标志设置为false,从而关闭全局中间件。

路由通配符

也支持基于模式的路由。例如,星号被用作通配符,将匹配任何字符的组合:

forRoutes({ path: "ab*cd", method: RequestMethod.ALL });

'ab*cd' 路由路径将匹配 abcd、ab_cd、abecd,等等。字符"?“、”+“、”*“和”()"可以在路径中使用,它们是对应于正则表达式的子集。连字符(-)和点(.)可以通过基于字符串的路径进行字面解释。

中间件消费者

MiddlewareConsumer是一个辅助类。它提供了几种内置方法来管理中间件。所有这些都可以简单地以Fluent styple。forRoutes()方法可以采用单个字符串、多个字符串、RouteInfo对象、一个控制器类甚至多个控制器类。在大多数情况下,你可能只会传递一个以逗号分隔的控制器列表。下面是单个控制器的示例:

import { Module, NestModule, MiddlewareConsumer } from "@nestjs/common";
import { LoggerMiddleware } from "./common/middleware/logger.middleware";
import { CatsModule } from "./cats/cats.module";
import { CatsController } from "./cats/cats.controller";
@Module({
  imports: [CatsModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(LoggerMiddleware).forRoutes(CatsController);
  }
}

apply() 方法可以使用单个中间件,也可以使用多个参数来指定多个多个中间件。

路由排除

有时我们希望从应用中间件中排除某些路由。我们可以使用 exclude() 方法轻松排除某些路由。此方法可以采用单个字符串、多个字符串或标识要排除的路由的 RouteInfo 对象,如下所示:

consumer
  .apply(LoggerMiddleware)
  .exclude(
    { path: "cats", method: RequestMethod.GET },
    { path: "cats", method: RequestMethod.POST },
    "cats/(.*)"
  )
  .forRoutes(CatsController);

exclude() 方法支持使用正则表达式包路径的通配符参数。

在上面的例子中,LoggerMiddleware将被绑定到 CatsController 中定义的所有路由,除了传递给 exclude() 方法的三个路由。

函数式中间件

我们一直在使用的LoggerMiddleware类非常简单。它没有成员,没有其他方法,也没有依赖项。为什么我们不能在一个简单的函数而不是类中定义它?事实上,我们可以。这种类型的中间件称为函数式间件。让我们将LoggerMiddleware中间件从基于类的中间件转换为函数式间件,以说明其中的区别:

import { Request, Response, NextFunction } from "express";
export function logger(req: Request, res: Response, next: NextFunction) {
  console.log(`Request...`);
  next();
}

AppModule中使用它:

consumer.apply(logger).forRoutes(CatsController);

只要中间件不需要任何依赖项,请考虑使用更简单的 函数式中间件 替代方法。

多个中间件

如上所述,为了绑定多个按顺序执行的中间件,只需在 ‘apply()’ 方法中提供一个逗号分隔的列表:

consumer.apply(cors(), helmet(), logger).forRoutes(CatsController);

全局中间件

如果我们想一次将中间件绑定到每个注册的路由,我们可以使用INestApplication 实例提供的 use()方法:

const app = await NestFactory.create(AppModule);
app.use(logger);
await app.listen(3000);

无法访问全局中间件中的 DI 容器。当使用app.use() 时,您可以使用[函数式中间件](中间件#functional-middleware)代替。或者,您可以使用类中间件并将其与AppModule或任何其他模块)中的.forRoutes(”*“)一起使用。

到此这篇关于Node.js使用Middleware中间件教程详解的文章就介绍到这了,更多相关Node.js Middleware内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     801人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     348人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     311人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     432人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     220人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-前端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯