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

NestJS处理application/json请求时request的data、end事件未触发问题

问题根因

NestJS 默认内置了 body-parser 中间件,会自动预处理 content-type 为 application/json、application/x-www-form-urlencoded 等常见类型的请求:

  • 中间件会提前读取完整的请求流,解析成JS对象挂载到 request.body 属性上
  • 流被消费完毕后就不会再触发 data 和 end 事件,所以你手动监听这两个事件没有响应
  • text/plain 类型不在 body-parser 默认处理范围内,请求流没有被提前消费,所以你的监听逻辑可以正常执行

解决方案

方案1(最推荐):直接使用NestJS解析好的请求体

无需自己监听流读取请求体,直接用框架提供的 @Body() 装饰器获取解析结果即可,改造后代码如下:
控制器代码:

@Public()
@Post(SERVER_COVID_A_CASA_CARE_PLAN_NOTIFICATION_PATH)
getNotification(@Body() body: any, @Res() response: Response) {
  // 直接把解析好的body传给facade,也可以根据需要转成JSON字符串
  this.facade.manageCarePlanNotification(JSON.stringify(body), response);
}

facade 代码简化为:

manageCarePlanNotification(bodyStr: string, response: Response) {
  this.manageCarePlanNotificationRequest(bodyStr, response);
}

方案2:关闭指定路由的bodyParser预处理

如果你确实需要自行处理原始请求流,可以针对当前路由关闭 body-parser 的自动处理:

  1. 全局关闭默认bodyParser:
// main.ts
const app = await NestFactory.create(AppModule, {
  bodyParser: false
});
  1. 按需为其他需要自动解析的路由挂载bodyParser中间件,或者只针对当前路由使用raw中间件处理原始流。

方案3:兼容现有逻辑无需大改

直接判断请求类型,application/json 类型直接从 request.body 取解析好的对象转字符串即可:

manageCarePlanNotification(request: Request, response: Response) {
  // 新增判断:如果body已经被解析过,直接用
  if (request.headers['content-type'] === 'application/json' && request.body) {
    this.manageCarePlanNotificationRequest(JSON.stringify(request.body), response);
    return;
  }

  // 原有处理text/plain的逻辑保留
  let jsonBodyReq = '';
  request.on('data', function (data) {
    jsonBodyReq += data;
  });
  request.on('end', () => {
    this.manageCarePlanNotificationRequest(jsonBodyReq, response);
  });
  request.on('error', function (e) {
    console.log(e.message);
  });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 21:45:03