【发布时间】:2021-09-12 18:12:58
【问题描述】:
我最近刚刚开始了一个关于如何使用 Node js 和 socket.io 制作多人 snake.io 游戏的在线教程。
https://www.youtube.com/watch?v=ppcBIHv_ZPs
客户端的设置非常顺利,但是一旦我尝试建立套接字(视频中为 15:20),我在客户端浏览器 chrome 控制台中遇到错误,试图建立通信。一开始我收到如下错误
127.0.0.1/:1 访问 XMLHttpRequest at 来自原点“http://127.0.0.1:8080”的“http://localhost:3000/socket.io/?EIO=3&transport=polling&t=NfTLuxq”已被 CORS 策略阻止:否“访问控制允许-请求的资源上存在 Origin 标头。
然后我对什么是 CORS 进行了一些研究,据我了解,它就像一个限制不同 URL 之间连接的安全协议,出于安全原因,此错误需要标头?
我看到一个用户说他做到了,所以客户端和服务器端的 socket.io 库是相同的。因此,我从服务器端删除了 socket.io 文件,并使用我通过 CDN 拉入客户端的相同版本重新安装了它们。我使用了命令'yarn add socket.io@2.3.0'。我认为这可以解决问题,但是我收到了另一个错误,
"加载资源失败: 网络::ERR_CONNECTION_REFUSED"
我也不明白为什么在这个项目中我们从 index.html 中的 cdn 中提取 socket.io(我不确定它是如何工作的),然后使用 yarn 在服务器端,然后我们必须使用“require”将它再次导入。我不确定我是否理解这两种导入 socket.io 的方法之间的区别,以及为什么我们使用两种不同的方法。
如果能帮助我解决我为什么会收到这些错误和上一个问题的一些困惑,我们将不胜感激!
index.html 的代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>>MultiPlayer Snake</title>
<!-- Import bootstrap-css --> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css"
integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
</head>
<body>
<!-- Create a section that is 100% height of window. -->
<div class="container h-100">
<section class="vh-100">
<div id="gameScreen" class="h-100">
<!-- Center canvas both horizontally and vertically using a few bootstrap classes -->
<div class="d-flex flex-column align-items-center justify-content-center h-100">
<canvas id="canvas"></canvas>
</div>
</div>
</div>
</section>
<!-- Pulling in socket.io from a cdn? -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script>
<!-- Importing index.js -->
<script src="index.js"></script>
</body>
</html>
index.js 的代码
const BG_COLOUR = '#231f20';
const SNAKE_COLOUR = '#c2c2c2';
const FOOD_COLOUR = '#e66916';
const socket = io('http://localhost:3000');
socket.on('init', handleInit);
// Get a hold of the game screen div from html
const gameScreen = document.getElementById('gameScreen');
// Create canvas and context elements, context->state
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,
};
// Initialize everything
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);
}
server.js 的代码
// Import socket.io
const io = require('socket.io')();
// add listener
io.on('connection', client => {
// Callback function
// Raise an event.
client.emit('init', {data: 'hello world' });
});
io.listen(3000);
我的文件结构。 My file sctructure
在收到这个问题的反馈后,我添加了处理 cos 的代码,但这次又收到了一条错误消息
CORS 已阻止从源“http://127.0.0.1:8080”访问“http://localhost:3000/socket.io/?EIO=3&transport=polling&t=NfUVBF5”处的 XMLHttpRequest策略:“Access-Control-Allow-Origin”标头的值“http://localhost:8080”不等于提供的来源。
我在 server.js 中编写了这段代码
const io = require("socket.io")( {
cors: {
origin: "http://localhost:8080",
methods: ["GET", "POST"]
}
});
【问题讨论】:
-
如果没有适当的 cors 处理,您将无法通过 127.0.0.1:8080 访问该站点,并期望它连接到 localhost:3000 的端点,主机和端口与 cors 有关
标签: javascript node.js websocket server socket.io