一、全局中间件使用

1. 创建中间件

1.1 创建一个简单的中间件函数

// src/middleware/logger.middleware.ts
import { Request, Response, NextFunction } from 'express';

export function logger(req: Request, res: Response, next: NextFunction) {
  console.log(`Request: ${req.method} ${req.url}`);
  next();
}

2. 注册中间件

2.1 全局中间件

main.ts 中注册全局中间件:使用app.use(logger)

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { Request, Response, NextFunction } from 'express';
function logger(req: Request, res: Response, next: NextFunction) {
  console.log(`Request: ${req.method} ${req.url}`);
  next();
}
async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.use(logger); // 注册全局中间件
  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();

二、模块中间件使用

在 NestJS 中,模块中间件是在特定模块的请求到达控制器之前执行的中间件。你可以在模块中使用 configure 方法来注册中间件。下面详细介绍模块中间件的注册和使用语法。

1. 创建中间件

首先,你需要创建一个中间件类。中间件类是一个实现了 NestMiddleware 接口的类,该接口要求你实现一个 use 方法。

示例中间件

// logger.middleware.ts
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... ${req.method} ${req.url}`);
    next();
  }
}

2. 注册模块中间件

在模块中注册中间件需要使用 configure 方法。configure 方法接受一个 MiddlewareConsumer 对象,你可以使用这个对象来应用中间件到特定的路由。

示例模块

// user.module.ts
import { Module, MiddlewareConsumer } from '@nestjs/common';
import { UserController } from './user.controller';
import { UserService } from './user.service';
import { LoggerMiddleware } from '../common/middleware/logger.middleware';

@Module({
  controllers: [UserController],
  providers: [UserService],
})
export class UserModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes('users'); // 指定路由
  }
}

3. 详细说明

  • apply** 方法**:用于指定要应用的中间件。
  • forRoutes** 方法**:用于指定中间件应用的路由。可以是一个字符串、一个路由对象、一个控制器类或一个数组。

示例:应用到多个路由

// user.module.ts
import { Module, MiddlewareConsumer } from '@nestjs/common';
import { UserController } from './user.controller';
import { UserService } from './user.service';
import { LoggerMiddleware } from '../common/middleware/logger.middleware';

@Module({
  controllers: [UserController],
  providers: [UserService],
})
export class UserModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes(['users', 'profile']); // 指定多个路由
  }
}

示例:应用到特定控制器

// user.module.ts
import { Module, MiddlewareConsumer } from '@nestjs/common';
import { UserController } from './user.controller';
import { UserService } from './user.service';
import { LoggerMiddleware } from '../common/middleware/logger.middleware';

@Module({
  controllers: [UserController],
  providers: [UserService],
})
export class UserModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes(UserController); // 指定控制器
  }
}

示例:应用到特定路由路径

// user.module.ts
import { Module, MiddlewareConsumer } from '@nestjs/common';
import { UserController } from './user.controller';
import { UserService } from './user.service';
import { LoggerMiddleware } from '../common/middleware/logger.middleware';

@Module({
  controllers: [UserController],
  providers: [UserService],
})
export class UserModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes({ path: 'users/:id', method: RequestMethod.GET }); // 指定特定路由路径和方法
  }
}

4. 多个中间件

你可以在 apply 方法中传入多个中间件。

示例:多个中间件

// user.module.ts
import { Module, MiddlewareConsumer } from '@nestjs/common';
import { UserController } from './user.controller';
import { UserService } from './user.service';
import { LoggerMiddleware } from '../common/middleware/logger.middleware';
import { AuthMiddleware } from '../common/middleware/auth.middleware';

@Module({
  controllers: [UserController],
  providers: [UserService],
})
export class UserModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware, AuthMiddleware)
      .forRoutes('users'); // 指定路由
  }
}

总结

  • 全局中间件使用函数,模块中间件使用类
  • apply** 方法**:用于指定要应用的中间件。
  • forRoutes** 方法**:用于指定中间件应用的路由。可以是一个字符串、一个路由对象、一个控制器类或一个数组。
  • 多个中间件:可以在 apply 方法中传入多个中间件。

希望这些例子能帮助你更好地理解和使用 NestJS 中的模块中间件。如果你有任何进一步的问题或需要更详细的解释,请随时提问!

三、第三方中间件的使用

在 NestJS 中使用 cors 中间件非常简单。cors 是一个用于启用跨域资源共享(Cross-Origin Resource Sharing)的中间件,可以帮助你在开发和生产环境中处理跨域请求。以下是详细的步骤和示例代码:

1. 安装 cors 中间件

首先,你需要安装 cors 中间件:

npm install cors

2. 注册 cors 中间件

2.1 全局中间件

main.ts 中注册全局 cors 中间件:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as cors from 'cors';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  // 注册 cors 中间件
  // app.enableCors({
  //   origin: ['http://example.com'], // 允许的源
  //   methods: 'GET,HEAD,PUT,PATCH,POST,DELETE', // 允许的 HTTP 方法
  //   allowedHeaders: 'Content-Type, Accept', // 允许的请求头
  //   credentials: true, // 是否允许发送 cookies
  // });
  app.use(cors())
  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();

2.2 局部中间件

在模块或控制器中注册局部 cors 中间件:

// src/app.module.ts
import { Module, MiddlewareConsumer } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import * as cors from 'cors';

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(cors({
        origin: ['http://example.com'], // 允许的源
        methods: 'GET,HEAD,PUT,PATCH,POST,DELETE', // 允许的 HTTP 方法
        allowedHeaders: 'Content-Type, Accept', // 允许的请求头
        credentials: true, // 是否允许发送 cookies
      }))
      .forRoutes('api'); // 只在 /api 路径下应用 cors 中间件
  }
}

3. 配置选项

cors 中间件提供了多种配置选项,以下是一些常用的配置项:

  • origin:允许的源,可以是一个字符串、数组或函数。
  • methods:允许的 HTTP 方法,可以是一个字符串或数组。
  • allowedHeaders:允许的请求头,可以是一个字符串或数组。
  • exposedHeaders:暴露的响应头,可以是一个字符串或数组。
  • credentials:是否允许发送 cookies。
  • maxAge:预检请求的有效期,单位为秒。

4. 示例配置

以下是一个更详细的 cors 配置示例:

app.enableCors({
  origin: ['http://example.com', 'https://another-example.com'], // 允许的源
  methods: 'GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS', // 允许的 HTTP 方法
  allowedHeaders: 'Content-Type, Accept, Authorization', // 允许的请求头
  exposedHeaders: 'X-Custom-Header', // 暴露的响应头
  credentials: true, // 是否允许发送 cookies
  maxAge: 3600, // 预检请求的有效期,单位为秒
});

5. 非代码的解释性内容

  • 全局中间件:通过 app.enableCors 方法注册的 cors 中间件会应用于所有路由。
  • 局部中间件:通过 consumer.apply(cors(options)).forRoutes(routes) 方法,可以在特定的路由或路由组中应用 cors 中间件。
  • 跨域资源共享cors 中间件用于处理跨域请求,确保前端应用可以从不同的域名访问后端 API。
  • 配置选项cors 提供了丰富的配置选项,可以根据实际需求进行灵活配置。

通过以上示例和解释,你可以更好地理解和使用 NestJS 中的 cors 中间件功能。

最后修改:2024 年 11 月 22 日
如果觉得我的文章对你有用,请随意赞赏