一、全局中间件使用
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
中间件功能。