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

Express集成SocketIO时源匹配仍出现CORS错误的排查与解决

已解决:参考Phil的评论

解决方案:之前用的浏览器错误提示能力弱,换浏览器后5秒就找到问题

以下为原始问题,保留存档:

我遇到的问题是:当请求源与允许的源仅路径不同时,为何CORS仍会失败?错误信息如下:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:3030/socket.io/?EIO=4&transport=polling&t=OhAxRtW. (Reason: CORS header ‘Access-Control-Allow-Origin’ does not match ‘http://localhost:3030’).

根据CORS的定义:

跨源资源共享(CORS)是一种基于HTTP头的机制,允许服务器指定浏览器可以加载资源的源(域名、协议或端口)。

在我收到的错误信息中:

  • 两者协议相同:http
  • 两者域名相同:localhost
  • 两者端口相同:3030

既然协议、域名和端口都匹配,为何会出现这个错误?

直接对比:

http://localhost:3030/socket.io/?EIO=4&transport=polling&t=OhAxRtW
http://localhost:3030

CORS的源判断不应该包含路径,那为何会出现不匹配的情况?

我的代码如下:

// server

import express from 'express';
import http from 'http';
import { Server } from 'socket.io';

const app = express();
const httpServer = http.createServer(app);
const io = new Server(httpServer, {
  // @ts-expect-error
  cors: {
    origin: "http://localhost:3030"
  }
});

const port = 3030;

io.on('connection', (socket) => {
  console.log('A user connected');
  
  // Handle socket events here
  socket.on('data', (payload) => {
    console.log(payload);
  });

  socket.on('disconnect', () => {
    console.log('User disconnected');
  });
});

httpServer.listen(port, () => {
  console.log(`Server is running on port ${port}`);
});
// client

'use client';

import React, { useEffect, useState } from 'react';
import io, { Socket } from 'socket.io-client';


export const SocketTest = (): JSX.Element => {
  const [socket, setSocket] = useState<Socket | null>(null);

  useEffect(() => {
    const skt = io('ws://localhost:3030');
    setSocket(skt);
    skt.on('connect', () => {
      console.log('Connected to Socket.io');
    });

    // Handle socket events here

    return () => {
      skt.disconnect();
    };
  }, []);

  return (
    <div>
      <h1>Socket.io Demo</h1>
      <button
        onClick={() => {
          if (socket !== null) {
            console.log('socket emit');
            socket.emit("data", { message: "client data" });
          }
        }}
      >clicky</button>
    </div>
  );
}

export default SocketTest;

注意:如果将cors: { origin: ...改为通配符,一切正常,但我不想在生产代码中使用通配符。

cors: {
    origin: "*"  // works
  }

根据Socket.io的排查建议,我用curl测试,结果正常,即使CORS请求失败时也是如此:

我的curl命令及结果:

$ curl "http://localhost:3030/socket.io/?EIO=4&transport=polling"

0{"sid":"g4HqqSTX0oXDcEJpAAAJ","upgrades":["websocket"],"pingInterval":25000,"pingTimeout":20000,"maxPayload":1000000}%

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 21:18:12