如何通过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
相关产品推荐
相关产品推荐

