为什么无法连接到我的 websocket 端点

问题描述 投票:0回答:1

我正在用vuejs + vite开发SPA

我的后端有一个 websocket 端点。

我可以通过 cli 工具连接到该 websocket

websocat

但是当尝试在 javascript 中连接时,firefox 和 chrome 都显示连接错误。

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 连接:

我的打字稿代码:

  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: 

如果重要的话,证书是从 Let's Encrypt 获得的。

更新:

使用wireshark,我将问题范围缩小到vite代理服务器响应403:

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]

javascript vue.js websocket vite
1个回答
0
投票

事实证明:

后端服务器返回403响应。

对我来说是 spring boot + tomcat,我需要设置允许的来源:

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    @Autowired
    private SEAExportWSHandler seaExportWSHandler;

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(seaExportWSHandler, "/export/**").setAllowedOriginPatterns("*");
    }

}

但奇怪的是,chrome 浏览器吞下了 403 响应并给出空的错误消息。

© www.soinside.com 2019 - 2024. All rights reserved.