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

NodeJS发送大体积POST JSON请求在低配置设备上被截断问题

问题根因定位
    1. Content-Length字段赋值错误
      你代码里给Content-Length赋值用的是body.length,这个值是字符串的字符数,而HTTP协议要求的Content-Length是请求体的字节数。如果JSON中存在多字节UTF-8字符(比如中文、特殊符号),字符数会小于字节数,导致你填写的Content-Length比实际要发送的字节数小,服务器收到指定长度的内容后就会停止读取,自然会截断末尾内容。你手动加4个空格刚好补上了缺失的字节数差值,所以临时生效。
    1. 未等待请求完全发送就结束进程
      你用stream.pipe(req)发送数据,但没有监听请求的finish事件,也没有阻塞进程等待发送完成。台式机性能好,IO调度优先级高,数据能快速全部写入内核TCP缓冲区;而旧笔记本性能弱,TCP发送缓冲区更小,数据还没完全写入缓冲区时进程就已经退出,未发送的尾部数据直接被丢弃。
    1. 不必要的流转换引入额外风险
      三百多KB的请求体完全可以直接写入请求对象,不需要额外转成Readable流再pipe,流的背压处理逻辑在性能较弱的设备上可能出现未覆盖的边界问题。
修复方案

第一步:修正Content-Length赋值

把headers里的Content-Length改为Buffer.byteLength(body, 'utf8'),确保值是实际的字节数。

第二步:简化发送逻辑,监听发送完成事件

直接用req.write+req.end发送数据,添加finish事件监听确认发送完成,避免进程提前退出:

const http = require('http');

const hostname = 'hostname';
const port = 3000;
const path = '/my/path';
const method = 'POST';

const body = JSON.stringify(VERYLARGEJSONOBJECT);
const bodyBytes = Buffer.byteLength(body, 'utf8');
console.log(`Sending ${bodyBytes} bytes:`);

const options = {
  hostname,
  port,
  path,
  method,
  headers: {
    'Content-Type': 'application/json',
    'Content-Length': bodyBytes
  }
};

const req = http.request(options, (res) => {
  console.log(`Response statusCode: ${res.statusCode}`);
  // 响应接收完成后再退出,可根据业务逻辑调整
  res.resume();
  res.on('end', () => {
    process.exit(0);
  });
});

req.on('error', (error) => {
  console.error(error);
  process.exit(1);
});

// 直接写入请求体后结束请求
req.write(body);
req.end();

// 监听finish事件确认所有数据已写入系统缓冲区
req.on('finish', () => {
  console.log('All data has been sent');
});

可选:大体积请求体背压处理

如果后续要发送更大的请求体,可以监听drain事件处理背压:

const writeRes = req.write(body);
if (!writeRes) {
  req.once('drain', () => {
    req.end();
  });
} else {
  req.end();
}
验证方法

在旧笔记本上运行修复后的代码,打印发送的字节数和服务器接收到的字节数,确认两者一致即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.16 10:24:03