如何拦截并重定向Server-Sent Events(SSE)请求至代理服务器?
解决SSE请求拦截重定向的问题
先修复你的nock挂起问题
你的nock代码之所以挂起,核心原因是SSE是流式响应——axios默认会等待整个响应体接收完成才会resolve Promise,但SSE连接会一直保持(不会发送结束信号),所以axios.get永远不会完成,导致nock的reply一直处于pending状态。
修改方案:放弃用axios转发,改用Node.js原生http/https模块发起请求,直接把代理服务器的响应流转发给nock的回复:
const http = require('http'); // 目标是HTTPS就用https模块 nock(originalDestination) .persist() .get(/.*/) .reply((uri) => { return new Promise((resolve, reject) => { const proxyReq = http.get(`${newDestination}${uri}`, (proxyRes) => { // 直接返回代理的状态码、响应流和响应头 resolve([proxyRes.statusCode, proxyRes, proxyRes.headers]); }); proxyReq.on('error', (err) => { resolve([500, `Proxy request failed: ${err.message}`]); }); }); });
这样nock会直接转发代理服务器的流式响应,完全适配SSE的持续连接特性,不会再挂起。
其他可选的拦截重定向方案
1. Axios请求拦截器(最简单直接)
如果你的请求都是通过axios发起的,直接用axios自带的拦截器修改请求目标,不需要额外工具:
axios.interceptors.request.use((config) => { // 把原目标地址替换成代理地址 if (config.url?.startsWith(originalDestination)) { config.url = config.url.replace(originalDestination, newDestination); } return config; });
这个方案完全绕过了mock工具,直接修改请求的最终地址,对SSE这类特殊请求兼容性最好。
2. Mockttp(更适合流式场景的Mock工具)
Mockttp天生支持流式响应,比nock更适配SSE、WebSocket这类长连接场景:
const mockttp = require('mockttp'); async function setupProxy() { const mockServer = await mockttp.getLocal().start(); // 把所有请求转发到代理服务器 mockServer.forAnyRequest().thenForwardTo(newDestination); // 把axios的默认请求地址指向mock服务器 axios.defaults.baseURL = mockServer.url; } setupProxy();
3. http-proxy-middleware(服务端反向代理场景)
如果是在Node.js服务端环境中做请求转发,可以用这个中间件搭建反向代理:
const { createProxyMiddleware } = require('http-proxy-middleware'); const express = require('express'); const app = express(); // 把所有匹配的请求转发到代理服务器 app.use('*', createProxyMiddleware({ target: newDestination, changeOrigin: true, pathRewrite: (path) => path.replace(originalDestination, '') // 根据需要调整路径 })); app.listen(3004); // 监听原目标的端口,把请求转发到代理
内容的提问来源于stack exchange,提问作者voice
相关产品推荐
相关产品推荐

