【Nest】中间件

一、中间件的创建与使用

1. 类中间件

通过实现 NestMiddleware 接口创建类中间件,需定义 use 方法:

typescript 复制代码
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(`[${new Date().toISOString()}] Request to: ${req.path}`);
    next(); // 必须调用 next() 传递请求
  }
}

注册方式 :在模块中通过 MiddlewareConsumer 配置作用范围:

typescript 复制代码
import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';

@Module({})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes('*'); // 应用到所有路由,或指定控制器/路径
      // 可以指定路由路径方法 或者 某个控制器类
      // forRoutes({path:'user',method:RequestMethod.GET})
      // forRoutes(UserController)
  }
}

2. 函数中间件

更轻量的方式,直接定义函数:

typescript 复制代码
export function logger(req: Request, res: Response, next: NextFunction) {
  console.log(`Request URL: ${req.url}`);
  next();
}

注册方式与类中间件相同。


二、全局中间件

全局中间件对所有路由生效,但仅支持函数形式 。需在 main.ts 中配置:

typescript 复制代码
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as cors from 'cors';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  // 应用全局中间件
  app.use(LoggerMiddleware); 
  await app.listen(3000);
}
bootstrap();

注意 :类中间件若需全局生效,需在模块中配置 forRoutes('*')


三、使用第三方中间件(以 CORS 为例)

bash 复制代码
npm install cors

npm install @types/cors -D

1. 通过 NestJS 内置模块

main.ts 中启用:

typescript 复制代码
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  // 配置 CORS
  app.enableCors({
    origin: 'http://localhost:3000', // 允许的域名
    methods: 'GET,POST',            // 允许的请求方法
  });
  await app.listen(3000);
}
bootstrap();

2. 直接使用 Express 中间件

例如使用 cors 包:

typescript 复制代码
import * as cors from 'cors';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.use(cors()); // 应用第三方中间件
  await app.listen(3000);
}

此方式更灵活,支持原生 Express 中间件的所有配置项。


四、高级用法示例

1. 多个中间件链式调用

typescript 复制代码
consumer
  .apply(Middleware1, Middleware2)
  .forRoutes(UserController);

中间件按顺序执行,若某个中间件未调用 next(),后续中间件和路由处理将终止。

2. 动态中间件配置

通过工厂函数传递参数:

typescript 复制代码
// 定义中间件生成函数
export function rateLimiter(options) {
  return (req, res, next) => {
    // 根据 options 实现限速逻辑
    next();
  };
}

// 注册时传入参数
consumer.apply(rateLimiter({ windowMs: 15000, max: 100 })).forRoutes('*');

总结

类型 适用场景 特点
类中间件 复杂逻辑、依赖注入 支持模块化配置,可复用性高
函数中间件 简单逻辑、快速实现 无需类结构,轻量级
全局中间件 跨路由统一处理(如日志) 仅函数形式,需在入口文件配置
第三方中间件 跨域、限速等通用功能 直接复用 Express 生态
相关推荐
闲人编程6 小时前
中间件开发与生命周期管理
缓存·中间件·生命周期·日志·扩展·codecapsule
添加shujuqudong1如果未回复14 小时前
用蜣螂优化(DBO)算法攻克置换流水车间调度问题
中间件
写代码的小阿帆16 小时前
消息队列中间件RabbitMQ基础——Spring AMQP、路由模型到可靠性
中间件·rabbitmq·java-rabbitmq
sugar椰子皮3 天前
【爬虫框架-6】中间件的另一种写法实现
爬虫·中间件
天海行者3 天前
多数据源 + ShardingSphere 分库分表 + 读写分离 实现方案
中间件·shardingsphere·dynamic
福大大架构师每日一题3 天前
eino v0.7.7 发布:新增文件系统中间件,优化序列化与反序列化,修复工具信息流问题
中间件
没有腰的嘟嘟嘟3 天前
从 0 到 1:我如何用 Spring Boot 3 + Redis 打造一个生产级通用幂等与防重中间件(含图解 + 代码 + 案例)
spring boot·redis·中间件·lua
浩浩测试一下3 天前
Kerberos 资源约束性委派误配置下的 S4U2self → S4U2proxy → DCSync 提权高阶手法链
安全·web安全·网络安全·中间件·flask·系统安全·安全架构
开酒不喝车4 天前
中间件AIDL HIDL区别总结
android·中间件
koping_wu4 天前
【中间件面试题】Mysql、Redis、MQ、ES、计算机网络
redis·mysql·中间件