如何排查Express中携带请求体的POST请求挂起无响应问题
问题排查与修复方案
核心问题定位
- 最可能的根因:你手动硬编码了
Content-Length为21,但实际发送的请求体"{\"test\":\"123\"}"的UTF-8编码长度仅为13字节,Express内置的jsonParser会严格等待剩余8字节的请求数据,一直收不到就会陷入无限挂起状态,和你提供的DEBUG日志卡在jsonParser环节的表现完全吻合。 - 其次检查请求参数错误:你调用
http.request时传入的method: POST没有给POST加引号,若你没有在其他地方定义POST变量,这里会抛出未定义错误,你能正常发送请求大概率是代码编写疏漏导致。 - 最后排查Express侧配置:确认你全局注册
express.json()中间件时没有配置异常的大小限制、校验规则,也没有其他自定义中间件在jsonParser之前劫持了请求体。
修复方案
客户端代码修复
删除硬编码的Content-Length,Node.js的http模块会自动根据你写入的请求体内容计算正确的长度,同时修正method的引号问题:
const the_Headers = { Authorization: "Bearer <token>", "x-custom-header": "custom-header-val", "content-type": "application/json" // 移除硬编码的content-length,交由http模块自动计算 } const data = "{\"test\":\"123\"}" const result = await new Promise((resolve,reject) => { const request = http.request( new URL("http://localhost/some/path"), {headers: the_Headers, method: "POST"}, // 给POST添加字符串引号 (res) => { res.setEncoding('utf8'); let responseBody = ''; res.on('data', (chunk) => { responseBody += chunk; }); res.on('end', () => { resolve({body: responseBody}); }); }); request.on('error', (err) => { reject({statusCode: 500, error: err}); }); if (data) request.write(data); request.end(); }) });
服务端代码优化
建议先判断req.body是否存在,避免无请求体时调用toString()抛出异常:
router.post("/some/path", async (req, res) => { res.status(200) .json({ message: "body is: " + (req.body ? JSON.stringify(req.body) : "empty")}); })
内容的提问来源于stack exchange,提问作者Elliott de Launay
相关产品推荐
相关产品推荐

