Socket.IO聊天应用开发出现CORS跨域拦截报错求解决方案
Socket.IO跨域问题解决方案
错误根因
你当前的CORS配置完全不生效,原因有两个:
- 你将CORS中间件挂载在了Express的
app实例上,但初始化Socket.IO时直接独立监听了8000端口,和Express服务没有关联,Express的CORS规则不会作用到Socket.IO的请求上 - 你配置的
origin值多了/index.html路径,CORS校验仅匹配源地址(协议+域名+端口),不需要带具体路径
修复代码
方案1:直接给Socket.IO配置CORS规则(无需使用Express的CORS中间件)
直接替换你的服务端代码即可:
//Node server which will handle socket io connections const io = require('socket.io')(8000, { cors: { // 仅填写协议+域名+端口,不要加后缀路径 origin: "http://127.0.0.1:5500", methods: ["GET", "POST"] } }); const users = {}; io.on('connection', socket => { socket.on('new-user-joined', name => { console.log(name); users[socket.id] = name; socket.broadcast.emit('user-joined', name); }); socket.on('send', message => { socket.broadcast.emit('receive', {message: message, name: users[socket.id]}) }); socket.on('disconnect', () => { socket.broadcast.emit('left', users[socket.id]); delete users[socket.id]; }) })
方案2:Socket.IO与Express共用HTTP服务
如果你需要同时使用Express的路由能力,可以用这种写法:
const express = require('express'); const app = express(); const http = require('http'); const server = http.createServer(app); const io = require('socket.io')(server, { cors: { origin: "http://127.0.0.1:5500", methods: ["GET", "POST"] } }); const users = {}; io.on('connection', socket => { // 原有逻辑保持不变 socket.on('new-user-joined', name => { console.log(name); users[socket.id] = name; socket.broadcast.emit('user-joined', name); }); socket.on('send', message => { socket.broadcast.emit('receive', {message: message, name: users[socket.id]}) }); socket.on('disconnect', () => { socket.broadcast.emit('left', users[socket.id]); delete users[socket.id]; }) }); // 注意这里用server监听端口,不是io监听 server.listen(8000, () => { console.log('服务已启动,端口8000'); })
其他注意事项
- 本地测试时如果源地址不固定,可以暂时将
origin设为*允许所有来源,生产环境再修改为正式的线上地址 - 要保证浏览器打开页面的地址和配置的
origin完全一致,比如你用http://localhost:5500打开页面,就要将origin配置为http://localhost:5500,localhost和127.0.0.1会被浏览器判定为不同的源 - 你的客户端代码还有其他语法问题需要修正:监听Socket.IO事件应该用
on方法而不是emit,比如socket.on('user-joined', () => {});HTML中输入框的id是text,JS中获取元素要对应改为document.getElementById("text")
内容的提问来源于stack exchange,提问作者Suvam Ray
相关产品推荐
相关产品推荐

