NestJS中间件在浏览器URL变更时异常触发的问题排查
NestJS HTTP日志中间件异常触发的原因与解决办法
异常触发的核心原因
- 浏览器自动预请求:现代浏览器(如Chrome、Edge)具备地址栏预测功能,当你在地址栏输入或修改URL时,浏览器会提前向服务器发起预加载请求。这类请求并非用户主动触发,但会正常到达NestJS服务器,进而触发中间件的日志逻辑。
- 缓存相关隐式请求:即便关闭了
etag配置,浏览器仍可能基于自身缓存策略发起验证请求(如携带If-Modified-Since请求头),或是直接重新请求资源,这些请求都会被中间件捕获并记录。 - 中间件的触发逻辑特性:NestJS中间件会拦截所有进入服务器的HTTP请求,无论请求发起方是用户主动操作还是浏览器自动行为,只要请求进入服务端处理流程,就会执行中间件代码。
针对性解决办法
1. 通过请求头过滤浏览器预请求
浏览器预加载/预渲染请求通常会携带特定请求头,可在中间件中判断这些头信息,跳过此类请求的日志记录:
@Injectable() class LogsMiddleware implements NestMiddleware { private readonly logger = new Logger('HTTP'); use(request: Request, response: Response, next: NextFunction) { // 识别并过滤预加载/预渲染请求 const purposeHeader = request.headers['purpose'] || request.headers['sec-purpose']; if (purposeHeader === 'prefetch' || purposeHeader === 'prerender') { return next(); } response.on('finish', () => { const { method, originalUrl } = request; const { statusCode, statusMessage } = response; const message = `${method} ${originalUrl} ${statusCode} ${statusMessage}`; this.logger.log(message); // 此处可添加写入数据库的逻辑 }); next(); } } export default LogsMiddleware;
2. 自定义日志过滤规则
若需要更精细的控制,可添加额外过滤条件,比如排除缓存相关的响应状态码,或是基于请求来源过滤:
response.on('finish', () => { const { method, originalUrl } = request; const { statusCode, statusMessage } = response; // 排除304缓存验证响应 if (statusCode === 304) { return; } const message = `${method} ${originalUrl} ${statusCode} ${statusMessage}`; this.logger.log(message); });
3. 限制中间件的绑定范围
确保中间件仅绑定到业务路由,而非全局所有路由(例如静态资源路由)。若之前是全局绑定,可改为针对特定模块或路由绑定:
// 在AppModule中配置中间件 export class AppModule implements NestModule { configure(consumer: MiddlewareConsumer) { consumer .apply(LogsMiddleware) .forRoutes('users', 'posts'); // 仅对指定业务路由生效 } }
内容的提问来源于stack exchange,提问作者Martheli
相关产品推荐
相关产品推荐

