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

如何通过http-proxy-middleware修改代理响应体?onProxyRes未等待end事件

问题:修改代理响应体时res.send未执行的解决办法

我尝试修改代理目标URL的HTML响应体,但res.send方法未执行,原因是onProxyRes函数未等待proxyRes.on('end', () => {})事件。

测试代码:

const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');

const app = express();

const onProxyRes = async function  (proxyRes, req, res) {
  let body = '';
  proxyRes.on('data', (chunk) => {
    body += chunk;
  });

  proxyRes.on('end', () => {
    res.send(body + ' modified part'); // Send the modified response
  });
};

;(async() => {
  const exampleProxy = createProxyMiddleware({
    target: 'https://example.com',
    changeOrigin: true,
    on: { proxyRes: onProxyRes }
  });
  app.use('/', exampleProxy);
  
  app.listen(3000)
})()

实际输出为https://example.com的源码。

但如果修改函数为:

const onProxyRes = async function  (proxyRes, req, res) {
  res.send('test'); // Send the modified response
};

可以成功将响应设置为"test",但我需要基于目标URL的实际响应体加上自定义修改内容,请问有什么解决办法?


解决办法

核心问题是http-proxy-middleware默认会自动转发代理响应的内容给客户端,导致你在end事件里的res.send被默认转发逻辑覆盖。需要先拦截默认转发行为,再手动处理响应体。

修改后的完整代码:

const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');

const app = express();

const onProxyRes = function (proxyRes, req, res) {
  // 移除默认的data/end事件监听,阻止自动转发
  proxyRes.removeAllListeners('data');
  proxyRes.removeAllListeners('end');

  let body = '';
  proxyRes.on('data', (chunk) => {
    body += chunk;
  });

  proxyRes.on('end', () => {
    // 复制原响应的状态码和响应头
    res.status(proxyRes.statusCode);
    Object.keys(proxyRes.headers).forEach(header => {
      res.setHeader(header, proxyRes.headers[header]);
    });
    // 返回修改后的响应体
    res.send(body + ' modified part');
  });
};

;(async() => {
  const exampleProxy = createProxyMiddleware({
    target: 'https://example.com',
    changeOrigin: true,
    on: { proxyRes: onProxyRes }
  });
  app.use('/', exampleProxy);
  
  app.listen(3000, () => {
    console.log('Proxy server running on port 3000');
  });
})()

注意事项

  • 不需要将onProxyRes设为async,此处无异步操作需要等待
  • 必须复制原响应的状态码和响应头,保证客户端拿到的响应与原目标一致(仅修改响应体)
  • 如果代理的是二进制内容(如图片),不要用字符串拼接,改用Buffer收集数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 03:34:56