You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React+Vite应用无法与Spring Boot后端建立WebSocket连接

问题场景

React+Vite应用运行在localhost:5173,Spring Boot后端运行在localhost:5729。前端尝试连接后端WebSocket服务时失败,但Postman可正常连接该服务,且Spring Boot端无任何日志输出。

前端App.jsx代码

import { useState } from 'react'
import './App.css'

function App() {
  const [list, setList] = useState([])

  var ws = new WebSocket("ws://localhost:5729/cp")

  ws.onmessage=(message)=>{console.log(message); setList([...list,message])};

  return (
    <ul>
      {list.map(element => {
        return (<li>element</li>);
      })
    }
    </ul>
  )
}

export default App

Spring Boot配置类代码

@Configuration
@EnableWebSocket
//@ServerEndpoint("/cp")
public class WebSocketConfig implements WebSocketConfigurer {

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(new Handler(),"/cp");
    }


    class Handler extends TextWebSocketHandler {

        private List<WebSocketSession> sessions = new CopyOnWriteArrayList<>();
        @Override
        public void afterConnectionEstablished(WebSocketSession session) {
            System.out.println("Session Added: "+session.getId());
            sessions.add(session);
        }

        @Override
        public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
            System.out.println("Closed");
        }

        @Override
        protected void handleTextMessage(WebSocketSession session, TextMessage message){
            for(var t: sessions){
                try {
                    t.sendMessage(message);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}

前端控制台错误信息

App.jsx:7 WebSocket connection to 'ws://localhost:5729/cp' failed: 
App.jsx:7 WebSocket connection to 'ws://localhost:5729/cp' failed: 

解决方案

1. 解决跨域问题

前端与后端端口不同属于跨域请求,Spring Boot的WebSocket配置需添加跨域支持,修改registerWebSocketHandlers方法:

@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
    registry.addHandler(new Handler(), "/cp")
            .setAllowedOrigins("http://localhost:5173"); // 允许前端域名访问
}

若需临时允许所有域名可使用"*",但生产环境不建议这么做。

2. 修复前端状态更新与渲染问题

当前onmessage中捕获的list是闭包初始值,状态更新会有异常,同时渲染未显示实际内容,建议调整:

ws.onmessage=(message)=>{
    console.log(message);
    setList(prevList => [...prevList, message.data]); // 用函数式更新获取最新状态,取message.data而非整个对象
};

渲染时添加key并显示实际内容:

{list.map((element, index) => {
    return (<li key={index}>{element}</li>);
})}

3. 规范WebSocket实例生命周期

组件每次渲染都会创建新连接,建议用useEffect包裹避免重复创建,同时在组件卸载时关闭连接:

import { useState, useEffect } from 'react'
import './App.css'

function App() {
  const [list, setList] = useState([])

  useEffect(() => {
    const ws = new WebSocket("ws://localhost:5729/cp")
    
    ws.onmessage=(message)=>{
        console.log(message);
        setList(prevList => [...prevList, message.data]);
    };

    return () => {
        ws.close();
    };
  }, []); // 空依赖确保只执行一次

  return (
    <ul>
      {list.map((element, index) => {
        return (<li key={index}>{element}</li>);
      })}
    </ul>
  )
}

export default App

内容的提问来源于stack exchange,提问作者Thug Life

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 14:46:30