NestJS中间件 #
什么是中间件? #
中间件是在路由处理程序之前执行的函数。中间件可以访问请求对象和响应对象,以及应用程序请求-响应周期中的下一个中间件函数。
中间件特点 #
- 执行任何代码
- 修改请求和响应对象
- 结束请求-响应周期
- 调用下一个中间件
创建中间件 #
类中间件 #
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()}] ${req.method} ${req.url}`);
next();
}
}
函数中间件 #
typescript
import { Request, Response, NextFunction } from 'express';
export function loggerMiddleware(
req: Request,
res: Response,
next: NextFunction,
) {
console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
next();
}
应用中间件 #
在模块中配置 #
typescript
import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { UsersController } from './users.controller';
import { LoggerMiddleware } from './logger.middleware';
@Module({
controllers: [UsersController],
})
export class UsersModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(LoggerMiddleware)
.forRoutes('users');
}
}
路由配置 #
typescript
consumer
.apply(LoggerMiddleware)
.forRoutes({ path: 'users', method: RequestMethod.GET });
多个路由 #
typescript
consumer
.apply(LoggerMiddleware)
.forRoutes('users', 'products');
排除路由 #
typescript
consumer
.apply(LoggerMiddleware)
.exclude(
{ path: 'users/health', method: RequestMethod.GET },
)
.forRoutes(UsersController);
多个中间件 #
typescript
consumer
.apply(LoggerMiddleware, AuthMiddleware)
.forRoutes('*');
全局中间件 #
使用实例方法 #
typescript
const app = await NestFactory.create(AppModule);
app.use(loggerMiddleware);
await app.listen(3000);
使用模块配置 #
typescript
@Module({
imports: [],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(LoggerMiddleware)
.forRoutes('*');
}
}
中间件示例 #
日志中间件 #
typescript
import { Injectable, NestMiddleware, Logger } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';
@Injectable()
export class LoggingMiddleware implements NestMiddleware {
private readonly logger = new Logger(LoggingMiddleware.name);
use(req: Request, res: Response, next: NextFunction) {
const { method, originalUrl, ip } = req;
const startTime = Date.now();
res.on('finish', () => {
const { statusCode } = res;
const duration = Date.now() - startTime;
this.logger.log(
`${method} ${originalUrl} ${statusCode} ${duration}ms - ${ip}`,
);
});
next();
}
}
认证中间件 #
typescript
import {
Injectable,
NestMiddleware,
UnauthorizedException,
} from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';
@Injectable()
export class AuthMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
const token = req.headers.authorization?.split(' ')[1];
if (!token) {
throw new UnauthorizedException('Token not found');
}
try {
const decoded = this.verifyToken(token);
req.user = decoded;
next();
} catch (error) {
throw new UnauthorizedException('Invalid token');
}
}
private verifyToken(token: string) {
// Token verification logic
return { id: 1, email: 'user@example.com' };
}
}
CORS中间件 #
typescript
import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';
@Injectable()
export class CorsMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
res.header('Access-Control-Allow-Origin', '*');
res.header(
'Access-Control-Allow-Methods',
'GET,HEAD,PUT,PATCH,POST,DELETE',
);
res.header(
'Access-Control-Allow-Headers',
'Content-Type, Authorization',
);
if (req.method === 'OPTIONS') {
res.sendStatus(204);
return;
}
next();
}
}
请求限流中间件 #
typescript
import {
Injectable,
NestMiddleware,
HttpException,
HttpStatus,
} from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';
@Injectable()
export class RateLimitMiddleware implements NestMiddleware {
private requests = new Map<string, number[]>();
private readonly limit = 100;
private readonly windowMs = 60000;
use(req: Request, res: Response, next: NextFunction) {
const ip = req.ip;
const now = Date.now();
if (!this.requests.has(ip)) {
this.requests.set(ip, []);
}
const timestamps = this.requests.get(ip)!;
const validTimestamps = timestamps.filter(t => now - t < this.windowMs);
if (validTimestamps.length >= this.limit) {
throw new HttpException(
'Too many requests',
HttpStatus.TOO_MANY_REQUESTS,
);
}
validTimestamps.push(now);
this.requests.set(ip, validTimestamps);
next();
}
}
请求体解析中间件 #
typescript
import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';
@Injectable()
export class BodyParserMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
let body = '';
req.on('data', chunk => {
body += chunk.toString();
});
req.on('end', () => {
try {
req.body = JSON.parse(body);
next();
} catch (error) {
next(error);
}
});
}
}
依赖注入 #
中间件支持依赖注入:
typescript
import { Injectable, NestMiddleware } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
@Injectable()
export class ConfigMiddleware implements NestMiddleware {
constructor(private configService: ConfigService) {}
use(req: Request, res: Response, next: NextFunction) {
const apiKey = this.configService.get('API_KEY');
req.headers['x-api-key'] = apiKey;
next();
}
}
中间件执行顺序 #
text
请求 → 全局中间件 → 模块中间件 → 路由中间件 → 控制器 → 服务 → 响应
中间件最佳实践 #
1. 单一职责 #
每个中间件只做一件事:
typescript
// 日志中间件只负责日志
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
console.log(`${req.method} ${req.url}`);
next();
}
}
// 认证中间件只负责认证
@Injectable()
export class AuthMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
// 认证逻辑
next();
}
}
2. 错误处理 #
在中间件中正确处理错误:
typescript
@Injectable()
export class ErrorHandlingMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
try {
next();
} catch (error) {
next(error);
}
}
}
3. 异步操作 #
处理异步操作:
typescript
@Injectable()
export class AsyncMiddleware implements NestMiddleware {
async use(req: Request, res: Response, next: NextFunction) {
await this.doSomethingAsync();
next();
}
private async doSomethingAsync() {
return new Promise(resolve => setTimeout(resolve, 100));
}
}
总结 #
本章学习了NestJS中间件:
- 中间件的概念和特点
- 类中间件和函数中间件
- 中间件的应用方式
- 常用中间件示例
- 中间件最佳实践
接下来,让我们学习 管道(Pipe)。
最后更新:2026-03-28