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

解析请求体后NodeJS http-proxy无响应,求解决方案

解决读取请求体后http-proxy代理无响应的问题

核心原因是:Node.js的请求对象是可读流,一旦被读取完毕,流就会处于结束状态,http-proxy无法再从中读取数据转发给目标服务,导致代理请求缺失请求体,目标服务无响应。

方案一:读取请求体后重建可读流

读取完请求体的buffer后,创建一个PassThrough流,将原始buffer写入新流,再替换原请求对象的流相关方法,让http-proxy能从新流中读取数据。

const express = require('express');
const httpProxy = require('http-proxy');
const { PassThrough } = require('stream');

const proxy = httpProxy.createProxyServer({});
const app = express();

app.post('*', async function(req, res) {
    // 读取原始请求体
    const buffers = [];
    for await (const chunk of req) {
        buffers.push(chunk);
    }
    const requestBuffer = Buffer.concat(buffers);
    const bodyData = JSON.parse(requestBuffer.toString());
    console.log(bodyData);

    // 创建新的可读流,写入原始请求体数据
    const passThroughStream = new PassThrough();
    passThroughStream.end(requestBuffer);

    // 替换请求对象的流方法,让proxy能读取新流
    req.pipe = passThroughStream.pipe.bind(passThroughStream);
    req.read = passThroughStream.read.bind(passThroughStream);
    req.on = passThroughStream.on.bind(passThroughStream);
    req.emit = passThroughStream.emit.bind(passThroughStream);
    req.readable = true;

    // 根据业务逻辑选择代理目标
    const target = bodyData.description.includes('payment') 
        ? 'http://localhost:3600/payment' 
        : 'http://localhost:3601/order';
    proxy.web(req, res, { target });
});

const server = app.listen(3602);

方案二:使用body-parser的raw模式解析

通过body-parser.raw()直接获取请求体的buffer,再重建流转发,这种方式更简洁,适合需要解析任意类型请求体的场景。

const express = require('express');
const httpProxy = require('http-proxy');
const bodyParser = require('body-parser');
const { PassThrough } = require('stream');

const proxy = httpProxy.createProxyServer({});
const app = express();

// 用raw模式解析所有类型的请求体,保留原始buffer
app.use(bodyParser.raw({ type: '*/*', limit: '10mb' }));

app.post('*', function(req, res) {
    try {
        const bodyData = JSON.parse(req.body.toString());
        console.log(bodyData);

        // 创建新流并写入原始请求体
        const passThroughStream = new PassThrough();
        passThroughStream.end(req.body);

        // 替换请求流方法
        req.pipe = passThroughStream.pipe.bind(passThroughStream);
        req.read = passThroughStream.read.bind(passThroughStream);
        req.on = passThroughStream.on.bind(passThroughStream);
        req.emit = passThroughStream.emit.bind(passThroughStream);
        req.readable = true;

        // 选择代理目标
        const target = bodyData.description.includes('payment') 
            ? 'http://localhost:3600/payment' 
            : 'http://localhost:3601/order';
        proxy.web(req, res, { target });
    } catch (err) {
        // 处理JSON解析失败的情况
        res.status(400).send('Invalid request body');
    }
});

const server = app.listen(3602);

注意事项

  • 根据请求体大小调整limit参数,避免因请求体过大导致解析失败
  • 无需修改Content-Length请求头,因为转发的是原始buffer,长度与原请求一致
  • 增加错误处理逻辑(如JSON解析失败),避免请求挂起

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 07:40:35