You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NestJS中能否同时使用Interceptor与@Response设置响应状态码?

解决NestJS拦截器与自定义响应状态码共存的问题

问题原因

当你在控制器中使用@Response()(或@Res())注入FastifyReply对象并直接调用send()时,NestJS会判定你已手动完成响应处理,控制器方法的返回值会被忽略,导致拦截器的next.handle()只能拿到undefined,最终无法执行响应包装逻辑。

解决方案

方案1:使用passthrough: true透传响应对象

通过在@Res()中添加passthrough: true配置,既可以手动设置响应状态码,又能让NestJS继续处理控制器的返回值,确保拦截器能拿到数据并完成包装。

控制器代码示例:

@UseInterceptors(TransformInterceptor)
@Post('some-path')
async someFunction(
  @Res({ passthrough: true }) reply: Fastify.FastifyReply,
) {
  // 根据逻辑设置状态码
  reply.status(isATeapot ? HttpStatus.I_AM_A_TEAPOT : HttpStatus.OK);
  // 直接返回数据,交给拦截器包装
  return someData;
}

拦截器无需修改,保持原有的包装逻辑即可。

方案2:统一返回格式,由拦截器处理状态码

控制器返回包含status和data的自定义对象,拦截器中读取状态码并设置到响应对象,同时完成数据包装。

控制器代码示例:

@UseInterceptors(TransformInterceptor)
@Post('some-path')
async someFunction() {
  const status = isATeapot ? HttpStatus.I_AM_A_TEAPOT : HttpStatus.OK;
  return { status, data: someData };
}

修改后的拦截器代码:

@Injectable()
export class TransformInterceptor<T> implements NestInterceptor<T, Response<T>> {
  intercept(context: ExecutionContext, next: CallHandler): Observable<Response<T>> {
    const httpContext = context.switchToHttp();
    const response = httpContext.getResponse<Fastify.FastifyReply>();
    
    return next.handle().pipe(
      map((result) => {
        // 处理包含状态码的自定义返回格式
        if (typeof result === 'object' && result.status !== undefined && result.data !== undefined) {
          response.status(result.status);
          return { data: result.data };
        }
        // 默认情况直接包装数据
        return { data: result };
      }),
    );
  }
}

方案3:跳过特定接口的拦截器(不推荐)

如果部分接口需要完全手动控制响应且不需要拦截器包装,可以使用@SkipInterceptor()装饰器跳过该接口的拦截器,但这会破坏响应格式的统一性,仅适合特殊场景。

@SkipInterceptor(TransformInterceptor)
@Post('some-path')
async someFunction(
  @Response() reply: Fastify.FastifyReply,
) {
  return reply
    .status(isATeapot ? HttpStatus.I_AM_A_TEAPOT : HttpStatus.OK)
    .send({ data: someData });
}

推荐方案

优先选择方案1,它既保留了拦截器的统一包装逻辑,又能灵活设置响应状态码,代码简洁且符合NestJS的设计理念。

内容的提问来源于stack exchange,提问作者okhobb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 12:50:21