首页 > 解决方案 > 拦截器中的 Nestjs 提前返回发送 [ERR_HTTP_HEADERS_SENT]

问题描述

如果用户在 jwt 中被标记为演示用户,我正在控制器上使用拦截器来提供模拟数据

它工作正常,模拟数据被馈送到客户端并且请求没有到达我的控制器,但我仍然在控制台中收到以下错误: UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

这是我的拦截器:

@Injectable()
export class UserPageStatsInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    // Let controller handle request
    if (!isDemo(context)) {
      return next.handle();
    }

    // Feed mock datas
    const res = context.switchToHttp().getResponse();

    res.status(200).send('Demo data');
  }
}

这是我的控制器:

@Get('statistics')
  @UseInterceptors(UserPageStatsInterceptor)
  getUsersGlobalStatistics(
    @Headers() headers: CustomHeaders,
    @Query() filters: BasicFiltersDTO,
    @Req() req,
  ): Promise<UserStatisticsDTO> {
    return 'Real data';
  }

我怀疑在我UserPageStatsInterceptor的请求继续在nestjs框架内部的某个地方之后,但我无法找到在哪里。我尝试在末尾添加returnor res.end(),但它没有任何改变。

请注意,这只发生在我的前端客户端上进行查询时,不会发生在邮递员中

提前谢谢你们!

标签: expresshttp-headersnestjs

解决方案


与其res.send()在拦截器内部调用,不如只返回一个包含您想要返回的数据的可观察对象?

@Injectable()
export class UserPageStatsInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    // Let controller handle request
    if (!isDemo(context)) {
      return next.handle();
    }

    return of('Demo data');
  }
}

这将使 Nest 仍然可以处理响应,并且不会妨碍实际运行您的服务代码。


推荐阅读