当前位置: 首页 > news >正文

NestJs-拦截器

NestJS 拦截器概述

拦截器(Interceptor)是 NestJS 的核心功能之一,用于在方法执行前后添加额外的逻辑。拦截器基于面向切面编程(AOP)思想,常用于日志记录、性能监控、响应格式统一等场景。

拦截器的核心功能

  • 方法执行前/后注入逻辑:可以在目标方法执行前后插入自定义代码。
  • 修改请求/响应数据:拦截请求或响应的数据流并对其进行转换。
  • 异常处理:捕获并处理目标方法抛出的异常。
  • 异步拦截:支持ObservablePromise的异步操作。

创建拦截器

拦截器是一个实现了NestInterceptor接口的类,需使用@Injectable()装饰器。核心方法是intercept,接收两个参数:

  • context: ExecutionContext:提供当前请求的上下文信息。
  • next: CallHandler:调用目标方法的控制器逻辑。
import{CallHandler,ExecutionContext,Injectable,NestInterceptor}from'@nestjs/common';import{map,Observable}from'rxjs';@Injectable()exportclassSerializeInterceptorimplementsNestInterceptor{intercept(context:ExecutionContext,next:CallHandler):Observable<any>{console.log('拦截器执行之前')constreq=context.switchToHttp().getRequest();console.log('请求对象',req)returnnext.handle().pipe(map((data)=>{console.log('拦截器执行之后')console.log('数据',data)returndata}));}}

注册拦截器

拦截器可以全局注册、模块注册或方法级注册:

全局注册

main.ts中使用SerializeInterceptor

app.useGlobalInterceptors(newSerializeInterceptor());
模块注册

通过模块的providers数组注册,并标记为可注入:

@Module({providers:[{provide:APP_INTERCEPTOR,useClass:SerializeInterceptor,},],})exportclassAppModule{}
方法级注册

直接在控制器方法上使用@UseInterceptors装饰器:

@Controller('users')exportclassUsersController{@UseInterceptors(SerializeInterceptor)@Get()findAll(){/* ... */}}

常见应用场景

统一响应格式

通过拦截器将控制器返回的数据包装为固定格式:

@Injectable()exportclassTransformInterceptorimplementsNestInterceptor{intercept(context:ExecutionContext,next:CallHandler):Observable<any>{returnnext.handle().pipe(map(data=>({success:true,data})));}}
性能监控

记录方法执行耗时:

@Injectable()exportclassTimingInterceptorimplementsNestInterceptor{intercept(context:ExecutionContext,next:CallHandler):Observable<any>{conststart=Date.now();returnnext.handle().pipe(tap(()=>console.log(`Execution time:${Date.now()-start}ms`)),);}}
缓存拦截

实现简单的缓存逻辑:

@Injectable()exportclassCacheInterceptorimplementsNestInterceptor{privatecache=newMap<string,any>();intercept(context:ExecutionContext,next:CallHandler):Observable<any>{constrequest=context.switchToHttp().getRequest();constkey=request.url;if(this.cache.has(key)){returnof(this.cache.get(key));}returnnext.handle().pipe(tap((data)=>this.cache.set(key,data)),);}}

高级用法

修改请求数据

通过拦截器预处理请求参数:

@Injectable()exportclassSanitizeInterceptorimplementsNestInterceptor{intercept(context:ExecutionContext,next:CallHandler):Observable<any>{constrequest=context.switchToHttp().getRequest();request.body=this.sanitize(request.body);returnnext.handle();}privatesanitize(data:any){// 实现数据清洗逻辑returndata;}}
异步拦截

结合rxjs操作符处理异步流:

@Injectable()exportclassTimeoutInterceptorimplementsNestInterceptor{intercept(context:ExecutionContext,next:CallHandler):Observable<any>{returnnext.handle().pipe(timeout(5000),// 5秒超时catchError((err)=>throwError(newRequestTimeoutException())),);}}

小栗子

实现请求敏感信息的过滤

import{CallHandler,ExecutionContext,Injectable,NestInterceptor}from'@nestjs/common';import{plainToInstance}from'class-transformer';import{map,Observable}from'rxjs';@Injectable()exportclassSerializeInterceptorimplementsNestInterceptor{constructor(privatedto?:any){}intercept(context:ExecutionContext,next:CallHandler):Observable<any>{console.log('拦截器执行之前')constreq=context.switchToHttp().getRequest();console.log('请求对象',req)returnnext.handle().pipe(map((data)=>{console.log('拦截器执行之后')console.log('数据',data)returnplainToInstance(this.dto,data,{// Expose 设置暴露字段// Exclude 设置排除字段excludeExtraneousValues:true,// 设置为true之后,所有经过拦截器的接口都需要设置Expose或者Exclude})}));}}

拦截器与过滤器的区别

  • 拦截器:作用于方法调用前后,可修改请求/响应数据流。
  • 异常过滤器:仅捕获异常,无法修改正常流程的数据。

最佳实践

  • 避免在拦截器中实现业务逻辑,保持职责单一。
  • 优先使用模块注册而非全局注册,便于测试和依赖管理。
  • 对于性能敏感的拦截器,可通过缓存减少重复计算。
http://www.gsyq.cn/news/122948.html

相关文章:

  • 28、UNIX 终端操作与测试实用指南
  • CPU 与 GPU 的区别与应用场景详解---从架构设计到真实应用的全面对比
  • 2025网络安全学习路线 非常详细 推荐学习
  • stm32毕设本科生任务书指导
  • 9个AI论文工具,助研究生高效完成学术写作!
  • Kubernetes 实操命令大全
  • bootchart数据量化工具使用
  • 集之互动AI创意视频解决方案:商业级可控,让品牌创意从“灵感”直达“落地”
  • CentOS 7.9 在 VMware 17.5.0 上的完整安装教程
  • 【2025实测】12款主流降ai率工具大汇总,论文降aigc一篇搞定(含免费降ai率工具) - 晨晨_分享AI
  • 详细揭秘如何使用 对哦 原理
  • 非期望超效率SBM模型:Matlab实现与探讨
  • 【linux内核】cephfs内核客户端回写
  • WebSocket 的使用
  • 欧几里得算法 求最大公约数(辗转相除法)
  • PFC2D5.0颗粒流离散元【人工合成岩体】河谷下切算例 本案例提供参考,可以自行修改参数或者...
  • 肠道病毒71型(EV71)重组蛋白——科研的关键工具与抗原标准
  • 开源赋能+技术深耕:AgentRun Sandbox SDK 重塑智能体开发新范式
  • 承兑汇票识别接口技术解析与应用实践
  • 控制流语句花括号的省略
  • 物联网智能灯具哪家好:TOP5权威榜单专业解析 - 品牌测评家
  • 基于深度学习的水果品质检测系统演示与介绍(YOLOv12/v11/v8/v5模型+Pyqt5界面+训练代码+数据集)
  • 轻量、高敏、高刚:BOTA传感器为UR机械臂注入力觉智能
  • 本地知识库:数据安全与智能管理的终极解决方案
  • Seekdb试用心得
  • 静待鱼跃龙门 —— 我是鲤鱼
  • VT五轴仿真模型与DMU五轴VT机床仿真模型:一键导入,轻松仿真
  • 协方差(covariance)与相关系数(correlation):数据关系的量化语言
  • 【建议收藏】AI大模型应用开发全攻略:Messages、RAG、Agent、ReAct等核心技术深度解析
  • 《创业之路》-742-技术创业者面临哪些问题?