You need to enable JavaScript to run this app. 如何解决ReactJS前端Socket.io客户端连接服务端socket失败问题
优惠活动
大模型
产品
解决方案
定价
更多

如何解决ReactJS前端Socket.io客户端连接服务端socket失败问题

你的报错核心是两个问题:

  • 前端Socket.IO客户端默认连接当前页面所在的localhost:3000,但你的Socket.IO服务端实际运行在5000端口,连接地址不匹配
  • 服务端Socket.IO没有配置跨域规则,就算地址正确也会被跨域策略拦截
  • 前端socket实例写在组件顶层,每次组件重渲染都会重复创建连接,造成资源浪费

第一步:修改服务端代码(SERVER.js)

调整Socket.IO初始化配置,添加跨域规则:
把原来的

const io = new Server(server);

替换为

const io = new Server(server, {
  cors: {
    origin: "http://localhost:3000" // 允许前端3000端口的跨域请求
  }
});

第二步:修改前端代码(ProductScreen.js)

  1. 新增状态存储回调状态,不要直接操作DOM,符合React的写法
  2. 把socket初始化放到useEffect中,明确指定服务端地址,添加组件卸载时的断连逻辑
    修改后的核心代码如下:
const ProductScreen = ({ match }) => {
  const [product, setProduct] = useState({});
  // 新增状态存储通话状态
  const [callStatus, setCallStatus] = useState('null');

  useEffect(() => {
    console.log('about to fetch product');
    const fetchProduct = async () => {
      console.log('Below is the id param waht the fuck is it?');
      console.log(match.params.id);
      const { data } = await axios.get(`http://localhost:5000/api/products/${match.params.id}`);
      setProduct(data);
    };
    fetchProduct();
  }, [match]);

  // 单独用useEffect处理socket逻辑,只在组件挂载时执行一次
  useEffect(() => {
    // 明确指定socket服务端地址为5000端口
    const socket = io('http://localhost:5000', { transports: ['websocket', 'polling'] });
    socket.on('status-update', function (call) {
      setCallStatus(call);
    });
    // 组件卸载时断开socket连接,避免内存泄漏
    return () => {
      socket.disconnect();
    }
  }, []);

  // 其余原有代码保持不变

渲染部分对应代码修改为:

<Col>
  {callStatus}
</Col>

修改完成后重启前后端服务即可正常连接。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 11:42:02