在http-proxy-middleware中捕获响应的问题
我正在编写一个代理,用来将WebSocket消息转发到后端服务器。
客户端通过HTTP发起请求,升级为WebSocket,并使用Sec-WebSocket-Key头。代理需要拦截该请求,为请求添加额外的头部,然后将请求转发给后端服务。
后端将接受升级请求,并返回一个Sec-WebSocket-Accept头,以及一个request-Id头。
在此通信过程中,我需要拦截响应,并获取后端服务返回的request-Id。
我已经编写了这段代码来获取request-Id。发起请求时,我可以在开发者工具的网络选项卡中看到来自 proxyReqWs 钩子的日志,但在网络选项卡中没有看到来自 proxyRes` hook. I can see that the proxy has relayed the response to the client as I can see Sec-Websocket-Accept and xyz-req-id 请求头 的 日志。代理应该已经拦截了响应并修改了头部名称,但并未发生。
这段代码里我还缺少什么?我需要修改响应头。
// 代理.js
export const setupProxy = (proxyConfig: ProxyConfig): RequestHandler => {
const proxyOptions: Options = {
target: proxyConfig.endpoint,
changeOrigin: true,
secure: true,
ws: true,
on: {
proxyReq: (proxyReq, req, res) => {
log('--------------------------------------');
logRequest(req as Request, 'Original Request from Client'); // Log original client request
proxyReq.setHeader('Authorization', `Bearer ${proxyConfig.details.apiKey}`);
logRequest(proxyReq, 'MODIFIED request to Backend)'); // Log modified request
},
proxyRes: (proxyRes, req, res) => {
logResponse(proxyRes, req as Request, 'Original Response from Backend'); // Log response from Backend
const isWebSocketSuccess = proxyRes.statusCode === 101;
let requestId: string | undefined;
if(isWebSocketSuccess) {
const requestId = proxyRes.headers['xyz-req-id'];
}
if (requestId) {
log(requestId);
proxyRes.headers['x-xyz-request-id'] = requestId;
}
delete proxyRes.headers['xyz-req-id'];
logResponse(proxyRes, req as Request, 'MODIFIED response to Client)'); // Log modified response
log('--------------------------------------');
},
proxyReqWs: (proxyReq, req, socket, options, head) => {
log('proxyReqWs event triggered for:', { method: req.method, url: req.url });
proxyReq.setHeader('Authorization', `Bearer ${proxyConfig.details.apiKey}`);
},
error: (err, req, res) => {
logError('Proxy Error:', err.message, 'Target:', target);
if (res.writeHead && !res.headersSent) {
res.writeHead(502, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'Bad Gateway', message: err.message }));
}
}
},
router: (req) => {
return proxyConfig.endpoint;
}
};
return createProxyMiddleware(proxyOptions);
};
// 服务器.js
import express from 'express';
import { setupProxy } from './proxy';
import config from './config';
import http from 'http';
const app = express();
const PORT = config.port;
// --- Express Middleware ---
// --- Health Check Endpoint ---
app.get('/health', (req, res) => {
console.log('Health Check Request Received');
res.status(200).send('Proxy is healthy!');
});
const proxy = setupProxy(config);
app.use('/', proxy);
// --- Start the Server ---
const server = http.createServer(app);
server.on('upgrade', proxy.upgrade);
server.listen(PORT, () => {
console.log(`[SERVER] Express Proxy listening on port ${PORT}`);
console.log(`[SERVER] Forwarding requests to Backend endpoint: ${config.endpoint}`);
});
// Handle server errors
server.on('error', (error: NodeJS.ErrnoException) => {
if (error.syscall !== 'listen') {
throw error;
}
const bind = typeof PORT === 'string' ? 'Pipe ' + PORT : 'Port ' + PORT;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(`${bind} requires elevated privileges`);
process.exit(1);
break;
case 'EADDRINUSE':
console.error(`${bind} is already in use`);
process.exit(1);
break;
default:
throw error;
}
});
export default app;
我应该如何修复这个代理,以便在拦截它们之后同时拦截请求和响应,并在拦截后调用外部服务?
解决方案
proxyRes 仅用于HTTP流量,拦截WebSocket响应不被支持:
可能的变通办法:
[ws] add options to transform client and server streams #1301
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。