问题描述
当使用 Socket.io 进行前端与服务端通信时,可能会出现跨域问题。例如,前端运行在 http://localhost:8000,而服务端运行在 http://localhost:9000,这时候如果前端直接使用 io('http://localhost:9000') 进行连接,就会报跨域错误。
解决方案
要解决跨域问题,可以在服务端设置 CORS(跨域资源共享)响应头,允许来自特定域的请求。但是 Socket.io 的跨域问题与普通 HTTP 请求有所不同,因为 Socket.io 在连接时要进行一次 HTTP 握手。因此需要在服务端设置特殊的响应头。
具体来说,可以在服务端代码中添加如下中间件:
// www.javascriptcn.com code example
const app = require('http').createServer();
const io = require('socket.io')(app);
app.on('request', function(req, res) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
});
app.listen(9000);在上述代码中,我们使用 http 模块创建了一个简单的 HTTP 服务,然后用 Socket.io 将其升级为 WebSocket 服务。在该服务的 request 事件监听器中,我们设置了以下 CORS 响应头:
Access-Control-Allow-Origin:允许任意来源的请求Access-Control-Allow-Methods:允许 GET、PUT、POST 和 DELETE 方法的请求Access-Control-Allow-Headers:允许发送包含Content-Type头的请求
这样,无论前端使用了哪个域名进行连接,服务端都会允许跨域请求。这就解决了跨域问题。
示例代码
以下是一个简单的示例,用于演示如何在 Socket.io 中解决跨域问题。
服务端代码
// www.javascriptcn.com code example
const app = require('http').createServer();
const io = require('socket.io')(app);
app.on('request', function(req, res) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
});
io.on('connection', function(socket) {
console.log('a user connected');
socket.on('disconnect', function() {
console.log('user disconnected');
});
});
app.listen(9000);前端代码
// www.javascriptcn.com code example
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Socket.io Example</title>
<script src="https://cdn.socket.io/socket.io-3.0.1.min.js"></script>
<script>
const socket = io('http://localhost:9000');
socket.on('connect', function() {
console.log('connected');
});
socket.on('disconnect', function() {
console.log('disconnected');
});
</script>
</head>
<body>
</body>
</html>在上述代码中,我们在前端页面中引入了 Socket.io 客户端库,然后创建了一个 Socket.io 实例并连接到服务端。在连接与断开时,我们分别在控制台输出了日志。由于服务端设置了 CORS 响应头,因此即使前端使用了 http://localhost:8000 进行连接,依然能够正常运行。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d69485a941bf7134c5e32c