http-proxy-middleware页面阻塞加载问题排查与解决求助
问题分析与解决方案
首先咱们拆解下页面一直加载的核心原因:
你在onProxyRes钩子中重写了res.write、res.writeHead和res.end这几个响应核心方法,拦截了代理服务器原本的响应流程。但关键问题在于:当代理响应的end事件触发(也就是proxyRes.on('end', ...)执行时),你只处理了响应体的buffer,却没有主动调用自己重写后的res.end(),这就导致浏览器一直在等待服务器发送响应结束的信号,自然会一直处于加载阻塞状态。
另外还有两个小细节需要修正:
- Node.js已经废弃了
new Buffer('')写法,建议改用Buffer.from('') - 你在
proxyRes.on('end')里给body赋值,但在res.end逻辑里却用了buffer.toString(),可以统一逻辑避免混淆
下面是修正后的完整代码,我标注了关键修改点:
var express = require('express'); var http = require('http'); var proxy = require('http-proxy-middleware'); function bodyTransform(body) { return body.replace('World', 'People'); } var onProxyRes = (proxyRes, req, res) => { const end = res.end; const writeHead = res.writeHead; let writeHeadArgs; // 替换废弃的Buffer构造函数 let buffer = Buffer.from(''); proxyRes.on('data', (chunk) => { console.log("inside: .on('data', ...)"); buffer = Buffer.concat([buffer, chunk]); }); proxyRes.on('end', () => { console.log("inside: .on('end', ...)"); // 关键修改:在这里调用重写后的res.end(),触发最终响应发送 res.end(); }); res.write = () => { }; res.writeHead = (...args) => { writeHeadArgs = args; }; res.end = () => { const output = bodyTransform(buffer.toString('utf8')); res.setHeader('content-length', output.length); if (writeHeadArgs) writeHead.apply(res, writeHeadArgs); end.apply(res, [output]); console.log('after: end.apply(res, [output]);'); }; } const portApp01 = 3001; const app01 = express() app01.get('/', (req, res) => { res.send('Hello World!'); }); app01.listen(portApp01, () => { console.log('app01 is listening on port: ' + portApp01); }); const portProxy = 3002; const appProxy = express() appProxy.use(proxy({ target:'http://localhost:3001', onProxyRes: onProxyRes, changeOrigin: true })); http.createServer(appProxy).listen(portProxy, function () { console.log('appProxy is listening on port: ' + portProxy); });
补充解释之前加return的两种情况:
- 在
res.writeHead = ...前加return:相当于直接跳过了所有响应拦截逻辑,代理服务器会直接把原响应发送给浏览器,所以页面能正常显示,但你的自定义响应体替换逻辑就完全不执行了。 - 在
res.writeHead = ...后加return:你已经重写了响应方法,但没有完成后续的响应发送流程,浏览器还是收不到结束信号,所以页面会永久处于加载状态。
现在运行修正后的代码,页面会正常显示Hello People!,终端日志也会完整输出,不会再出现阻塞问题。
内容的提问来源于stack exchange,提问作者davidesp
相关产品推荐
相关产品推荐

