Vue.js+Vite开发SPA无法连接WebSocket端点的问题排查
问题:Vue.js + Vite开发SPA时WebSocket连接失败(CLI工具可正常连接)
问题背景
使用Vue.js + Vite开发单页应用,后端已配置WebSocket端点。通过CLI工具websocat可正常连接该端点,但用JavaScript代码连接时,Firefox和Chrome均提示连接错误。证书来自Let's Encrypt,暂不确定是否与此问题相关。
Vite开发服务器代理配置
server: { // 允许IP访问 host: "portal-local.itps.xxx.com", // 应用端口 (默认:3000) port: Number(env.VITE_APP_PORT), // 运行是否自动打开浏览器 open: true, https: { key: fs.readFileSync( "/home/ggfan/2-work/git/itps/1A-IaaS-Manifests/kubernetes/1.27/ssl/certs/itps.xxx.com/privkey.pem" ), cert: fs.readFileSync( "/home/ggfan/2-work/git/itps/1A-IaaS-Manifests/kubernetes/1.27/ssl/certs/itps.xxx.com/fullchain.pem" ), }, proxy: { /** * 反向代理解决跨域配置 * http://localhost:3000/dev-api/users (F12可见请求路径) => http://localhost:8989/users (实际请求后端 API 路径) * * env.VITE_APP_BASE_API: /dev-api * env.VITE_APP_API_URL: http://localhost:8989 */ /* [env.VITE_APP_BASE_API]: { changeOrigin: true, target: "http://localhost:8080", rewrite: (path) => path.replace(new RegExp("^" + env.VITE_APP_BASE_API), ""), }, */ ["/oauth2"]: { changeOrigin: true, target: "https://api.itps.xxx.com", // secure: false, rewrite: (path) => path.replace(new RegExp("^" + env.VITE_APP_BASE_API), ""), /* cookieDomainRewrite: { "itps.xxx.com": "localhost", }, */ }, ["/pus"]: { changeOrigin: true, target: "http://localhost:8080", // secure: false, rewrite: (path) => path.replace(/^\/pus/, ""), /* cookieDomainRewrite: { "itps.xxx.com": "localhost", }, */ configure: proxyConfig, }, ["/ws"]: { changeOrigin: true, target: "http://localhost:8080", ws: true, secure: false, rewrite: (path) => path.replace(/^\/ws/, ""), configure: proxyConfig, }, }, }
websocat连接状态
websocat可正常连接后端WebSocket端点,连接状态无异常。
前端TypeScript连接代码
const ws = new WebSocket("wss://portal-local.itps.xxx.com:3000/ws/export/sea/users") ws.onopen = () => { ws.send("{}") } ws.onmessage = async (event) => { console.log(event.data) await writable.write(event.data) } ws.onclose = async (event) => { await writable.close() }
Chrome报错信息
SEAExportDialog.vue:104 WebSocket connection to 'wss://portal-local.itps.xxx.com:3000/ws/export/sea/users' failed:
排查更新(Wireshark抓包分析)
通过Wireshark抓包发现,Vite代理服务器返回403 Forbidden状态码:
Frame 22: 844 bytes on wire (6752 bits), 844 bytes captured (6752 bits) on interface lo, id 0 Ethernet II, Src: 00:00:00_00:00:00 (00:00:00:00:00:00), Dst: 00:00:00_00:00:00 (00:00:00:00:00:00) Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1 Transmission Control Protocol, Src Port: 38478, Dst Port: 3000, Seq: 683, Ack: 4150, Len: 778 Transport Layer Security Hypertext Transfer Protocol GET /ws/export/sea/users HTTP/1.1\r\n [Expert Info (Chat/Sequence): GET /ws/export/sea/users HTTP/1.1\r\n] [GET /ws/export/sea/users HTTP/1.1\r\n] [Severity level: Chat] [Group: Sequence] Request Method: GET Request URI: /ws/export/sea/users Request Version: HTTP/1.1 Host: portal-local.itps.xxx.com:3000\r\n Connection: Upgrade\r\n Pragma: no-cache\r\n Cache-Control: no-cache\r\n User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36\r\n Upgrade: websocket\r\n Origin: https://portal-local.itps.xxx.com:3000\r\n Sec-WebSocket-Version: 13\r\n Accept-Encoding: gzip, deflate, br, zstd\r\n Accept-Language: zh-CN,zh;q=0.9\r\n Cookie: _oauth2_proxy=X29hdXRoMl9wcm94eS00ZWU3OTM2NTIwYWYxNjBjNjZlNGQ4ODJkNTA0OGE4Yy5NM0FOUzVJRlBTV2JkN1g2Zlh6RWtB|1713431461|XkFGp00nkvsob926le3vxJ61wpGV44gtE1GeZcl4eEg=\r\n Cookie pair: _oauth2_proxy=X29hdXRoMl9wcm94eS00ZWU3OTM2NTIwYWYxNjBjNjZlNGQ4ODJkNTA0OGE4Yy5NM0FOUzVJRlBTV2JkN1g2Zlh6RWtB|1713431461|XkFGp00nkvsob926le3vxJ61wpGV44gtE1GeZcl4eEg= Sec-WebSocket-Key: FLMsmXSIxrT0bV1TA8yd/Q==\r\n Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits\r\n Sec-WebSocket-Protocol: WebSocket\r\n \r\n [Full request URI: https://portal-local.itps.xxx.com:3000/ws/export/sea/users] [HTTP request 1/1] [Response in frame: 24] Frame 24: 161 bytes on wire (1288 bits), 161 bytes captured (1288 bits) on interface lo, id 0 Ethernet II, Src: 00:00:00_00:00:00 (00:00:00:00:00:00), Dst: 00:00:00_00:00:00 (00:00:00:00:00:00) Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1 Transmission Control Protocol, Src Port: 3000, Dst Port: 38478, Seq: 4724, Ack: 1461, Len: 95 Transport Layer Security Hypertext Transfer Protocol HTTP/1.1 403 \r\n [Expert Info (Chat/Sequence): HTTP/1.1 403 \r\n] [HTTP/1.1 403 \r\n] [Severity level: Chat] [Group: Sequence] Response Version: HTTP/1.1 Status Code: 403 [Status Code Description: Forbidden] content-length: 0\r\n [Content length: 0] date: Thu, 18 Apr 2024 09:24:37 GMT\r\n \r\n [HTTP response 1/1] [Time since request: 0.011595626 seconds] [Request in frame: 22] [Request URI: https://portal-local.itps.xxx.com:3000/ws/export/sea/users]
内容的提问来源于stack exchange,提问作者WestFarmer
相关产品推荐
相关产品推荐

