跳转到内容
View in the app

A better way to browse. Learn more.

彼岸论坛

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.
欢迎抵达彼岸 彼岸花开 此处谁在 -彼岸论坛

[Node.js] NodeJS 如何代理 ws 协议的请求?

发表于

背景:使用 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 协议没反应。

Featured Replies

No posts to show

创建帐户或登录来提出意见

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.