小天管理 发表于 10月10日 发表于 10月10日 背景:使用 NodeJS 实现一个代理服务器,把服务器 URL 设置为电脑的全局代理,这样浏览器访问链接,把流量劫持到代理服务器,如何实现代理 http 协议和 ws 协议?比如在浏览器访问 a.com ,可以被代理服务器转发的 b.com ;访问 ws://a.com 可以被转发到 ws://127.0.0.1:8000 目前实现: const http = require('http'); const httpProxy = require('http-proxy'); // 创建一个代理服务器 const proxy = httpProxy.createProxyServer({ ws: true, // 启用 WebSocket 支持 changeOrigin: true // 修改源 }); // 创建 HTTP 服务器 const server = http.createServer((req, res) => { console.log(`收到 HTTP 请求: ${req.method} ${req.url}`); // 处理 HTTP 请求 proxy.web(req, res, { target: 'http://localhost:8080' }, (err) => { if (err) { console.error(`HTTP 代理错误: ${err.message}`); } }); }); // 处理 WebSocket 连接 server.on('upgrade', (req, socket, head) => { console.log(`收到 WebSocket 升级请求: ${req.url}`); proxy.ws(req, socket, head, { target: 'ws://localhost:8080' }, (err) => { if (err) { console.error(`WebSocket 代理错误: ${err.message}`); } }); }); // 设置代理服务器监听的端口 const PORT = 8002; server.listen(PORT, () => { console.log(`代理服务器已启动,正在监听端口 ${PORT}`); }); // 错误处理 proxy.on('error', (err, req, res) => { console.error('代理服务器错误:', err); if (!res.headersSent) { res.writeHead(500, { 'Content-Type': 'text/plain' }); } res.end('代理服务器出错'); }); // 添加代理事件监听器 proxy.on('proxyReq', (proxyReq, req, res) => { console.log(`代理请求: ${req.method} ${req.url} -> ${proxyReq.path}`); }); proxy.on('proxyRes', (proxyRes, req, res) => { console.log(`代理响应: ${req.url} - 状态码: ${proxyRes.statusCode}`); }); 在浏览器使用 SwitchyOmega ,设置代理 http://1270.0.0.1:8002 访问 http 请求:get http://t.weather.sojson.com/api/weather/city/101030100 可以看到打印日志 收到 HTTP request 请求: GET http://t.weather.sojson.com/api/weather/city/101030100 但是访问 ws 请求:ws://t.weather.sojson.com 没有打印任何日志,也就是说 upgrade 事件并没有触发。 问 AI ,回答可能是 WebSocket 握手过程中的协议升级可能在代理服务器之前就已经完成了。代理服务器可能只是在转发已经建立的 WebSocket 连接,而没有参与到协议升级的过程中。 有没有大佬帮忙分析下? ps: 在设置自签名证书后,可以代理 https 协议和 wss 协议,但是就是 ws 协议没反应。
已推荐帖子
创建帐户或登录来提出意见
您需要成为会员才能提出意见
创建帐户
注册成为会员.只要几个简单步骤!
注册帐户登录
已经有帐户? 请在此处登录.
现在登录