我正在开发一个项目,我已经设置了一个 socket.io 服务器。
服务器.js
const express = require('express');
const app = express();
const http = require('http');
const { Server } = require("socket.io");
const cors = require('cors');
const chatSocket = require('./socketListeners/chatListeners');
const room = require('./socketListeners/roomListeners');
const createRouter = require('./routes/create');
app.use('/creategame', createRouter);
app.use(cors());
const server = http.createServer(app);
const io = new Server(server, {
cors: {
origin: 'http://localhost:5173',
methods: ['POST', 'PUT']
}
});
io.on('connection', (socket) => {
console.log('a user connected');
chatSocket(socket);
room(socket);
});
server.listen(3000, () => {
console.log('server listening on port 3000');
});
初始套接字连接和 socketListener 文件运行正常,当我从 io 声明中删除 CORS 源时,它们停止工作。
chatListeners.js
type heremodule.exports = socket => {
socket.on('sendMessage', data => {
socket.to(data.roomId).emit("receiveMessage", data);
})
}
roomListeners.js
module.exports = socket => {
socket.on("joinRoom", data => {
socket.join(data)
})
}
当我希望我的服务器处理我的数据库时,我使用快速路由并从客户端获取请求。
创建.js
const express = require('express');
const router = express.Router();
const Room = require('../models/room');
router.post('/:id', async (req, res) => {
const room = new Room({
roomId: req.params.id,
});
try {
await room.save();
console.log(room);
} catch (error) {
console.error(error);
}
});
router.put('/:id/dicenum', async (req, res) => {
try {
const room = await Room.find({roomId: req.params.id});
room.diceNum = req.body.diceNum;
await room.save();
console.log(room);
} catch(error) {
console.error(error);
}
});
module.exports = router;
从反应组件中调用如下。
useEffect(() => {
fetch(`http://localhost:3000/creategame/${id}`, {
method: 'POST'
});
}, []);
useEffect(() => {
fetch(`http://localhost:3000/creategame/${id}/dicenum`, {
method: 'PUT',
body: {
diceNum: numOfDice
}
});
}, [numOfDice]);
问题是预检检查,它不知道我允许的来源,并且标头不存在。如果我以导致发送预检的方式修改 POST,则该检查也会失败。
(也许使用快速路由并不是一个好的做法,我真的不知道,如果使用套接字可以解决我的问题,请告诉我,否则必须有某种方法让两者都起作用)
我的飞行前响应标头像这样返回:
HTTP/1.1 200 好 X-Powered-By: Express 允许:放置 内容类型:text/html;字符集=utf-8 内容长度:3 ETag:W/“3-CRsM5C6wvZYWnqALFt2Tj21jrJU” 日期:2024 年 6 月 21 日星期五 20:22:05 GMT 连接:保持活动状态 保持活动:超时=5
我已经在互联网上搜索了几天,我尝试在我的服务器中移动 CORS 对象,使用 --disable-web-security 打开 chrome,并按照一些堆栈溢出答案的建议关闭广告块扩展,除了让服务器完全拒绝套接字连接之外,没有任何东西改变结果。
我知道 CORS 问题已经在这里被问了一百万次,但我见过的没有一个对我有帮助或似乎适用于我的情况,也许我的架构只是有缺陷,但我想我无论如何都会要求一个解决方案。
我解决了这个问题。如果有人有类似的问题/设置,我可以通过在 app.use(cors()) 中定义 cors 选项来修复它——我已经尝试过了——然后确保移动 app.use('/creategame', createRouter)低于该定义(事后显而易见)。
新的server.js
const express = require('express');
const app = express();
const http = require('http');
const { Server } = require("socket.io");
const cors = require('cors');
const chatSocket = require('./socketListeners/chatListeners');
const room = require('./socketListeners/roomListeners');
const createRouter = require('./routes/create');
app.use(cors({
origin: 'http://localhost:5173',
methods: ['POST', 'PUT']
}));
app.use('/creategame', createRouter);
const server = http.createServer(app);
const io = new Server(server, {
cors: {
origin: 'http://localhost:5173'
}
});
文件的其余部分保持不变。