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

如何修复多人贪吃蛇游戏开发中的Socket.io CORS错误

问题

开发多人贪吃蛇游戏时遇到CORS错误:

Access to XMLHttpRequest at 'http://localhost:5500/socket.io/?EIO=4&transport=polling&t=OAQWdpu' from origin 'http://127.0.0.1:5500' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The 'Access-Control-Allow-Origin' header has a value 'http://localhost:5500' that is not equal to the supplied origin.

使用VSCode的Live Server扩展在Edge浏览器中运行页面,跟着教程开发到15分钟左右卡住,尝试过Socket.io官方CORS配置但无效。相关代码如下:

server.js

const httpServer = require("http").createServer();
const io = require("socket.io")(httpServer, {
    cors: {
        origin: "http://localhost:5500",
        allowedHeaders: ["my-custom-header"],
        credentials: true
    }
});

io.on('connection', client =>{
client.emit('init', { data: 'hello world' });
});

io.listen(5500);

index.js

const BG_COLOUR = '#231f20';
const SNAKE_COLOUR = '#c2c2c2';
const FOOD_COLOUR = '#e66916';

// client-side
const socket = io('http://localhost:5500', {
  withCredentials: true,
  extraHeaders: {
    "my-custom-header": "abcd"
  }
}); 
socket.on('init', handleInit);

const gameScreen = document.getElementById('gameScreen');

let canvas, ctx;

const gameState = {
    player: {
        pos: {
            x: 3,
            y: 10,
        },
        vel: {
            x: 1,
            y: 0,
        },
        snake: [
            {x: 1, y: 10},
            {x: 2, y: 10},
            {x: 3, y: 10},
        ],
    },
    food: {
        x: 7,
        y: 7,
    },
    gridsize: 20,
};

function init(){
    canvas = document.getElementById('canvas');
    ctx = canvas.getContext('2d');

    canvas.width = canvas.height = 600;

    ctx.fillStyle = BG_COLOUR;
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    document.addEventListener('keydown', keydown);

}
function keydown(e){
    console.log(e.KeyCode);
}

init();

function paintGame(state){
    ctx.fillStyle = BG_COLOUR;
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    const food = state.food;
    const gridsize = state.gridsize;
    const size = canvas.width / gridsize;
    ctx.fillStyle = FOOD_COLOUR;
    ctx.fillRect(food.x * size, food.y * size, size, size);

    paintPlayer(state.player, size, SNAKE_COLOUR);
}

function paintPlayer(playerState, size, colour){
    const snake = playerState.snake;

    ctx.fillStyle = colour;
    for(let cell of snake){
        ctx.fillRect(cell.x * size, cell.y * size, size , size);
    }
}

paintGame(gameState);

function handleInit(msg){
    console.log(msg);
}

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>MultiPlayer Snake</title>
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">

</head>
<body>
  <section class="vh-100">
    <div class="container h-100">

     
      <div id="gameScreen" class="h-100">
        <div class="d-flex flex-column align-items-center justify-content-center h-100">

          <!-- <h1>Your game code is: <span id="gameCodeDisplay"></span></h1> -->

          <canvas id="canvas"></canvas>
        </div>
      </div>

    </div>
  </section>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.5.1/socket.io.js"></script>
  <script type="module" src="index.js"></script>
</body>
</html>

解决方案

错误核心是CORS的Origin严格匹配:服务器配置允许的Origin是http://localhost:5500,但Live Server实际运行页面的地址是http://127.0.0.1:5500,这两个地址在CORS规则里被视为不同源,导致验证失败。

有两种简单修复方式:

方式一:修改服务器CORS配置,允许两个源

将origin设置为包含两个地址的数组,覆盖两种访问场景:

const io = require("socket.io")(httpServer, {
    cors: {
        origin: ["http://localhost:5500", "http://127.0.0.1:5500"],
        allowedHeaders: ["my-custom-header"],
        credentials: true
    }
});

方式二:强制Live Server使用localhost

修改VSCode的Live Server配置:

  1. 打开VSCode设置(快捷键Ctrl+,)
  2. 搜索Live Server: Host
  3. 将值改为localhost
  4. 重启Live Server,页面将以http://localhost:5500打开,与服务器配置的Origin完全匹配

额外优化:简化不必要配置

如果不需要自定义头部和凭证,可简化配置减少干扰:
服务器端:

const io = require("socket.io")(httpServer, {
    cors: {
        origin: ["http://localhost:5500", "http://127.0.0.1:5500"]
    }
});

客户端:

const socket = io('http://localhost:5500');

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 11:09:26