Nodejs socket 跨域问题?

Nodejs socket 跨域问题?

火狐上提示的 已阻止交叉源请求:同源策略不允许读取 http://x.x.x.x:6789/socket.io/1/?t=1399889735198 上的远程资源。可以将资源移动到相同的域名上或者启用 CORS 来解决这个问题。 server端 var condb = require(’./condb’); var io = require(‘socket.io’).listen(6789,{log:false}); io.configure(function () { io.set(‘log level’, 1); io.set(‘origin’, ‘*’); }); io.sockets.on(‘connection’, function (socket) { socket.emit(‘news’, { hello: ‘world’ }); socket.on(‘nick’,function(data){ condb.add({‘nick’:data.name},socket.id) }); socket.on(‘all’,function(data){ socket.broadcast.emit(‘broad’,{‘type’:0,‘msg’:‘信息推送’,‘name’:‘SYSTEM’}); }); socket.on(‘disconnect’, function () { condb.del(socket.id) }); }); ~
客户端 <script type=“text/javascript” src=‘http://x.x.x.x:6789/socket.io/socket.io.js’></script> <script type=“text/javascript”> var socket; window.onload = function(){ socket = io.connect(‘http://x.x.x.x:6789’); socket.on(‘news’, function (data) { console.log(data); socket.emit(‘my other event’, { my: ‘data’ }); }); } function send(msg){ socket.emit(‘nick’,{‘name’:msg}) } </script>

客户端现在就是静态html页面 如果 我现在 在本地的页面 使用的话 会提示跨域

搜了好久都没解决,


4 回复

Node.js Socket 跨域问题

问题描述

在使用 Node.js 和 Socket.IO 实现 WebSocket 通信时,如果客户端和服务端不在同一个域名或端口下,可能会遇到跨域(CORS)问题。这会导致浏览器阻止客户端读取来自服务端的数据。

示例代码及解决方案

服务端代码

首先,我们需要在服务端配置 CORS 策略,允许跨域请求。

// server.js
const express = require('express');
const http = require('http');
const socketIo = require('socket.io');
const app = express();
const server = http.createServer(app);
const io = socketIo(server);

// 配置 CORS
io.origins('*:*');

io.on('connection', (socket) => {
    console.log('A user connected');

    socket.emit('news', { hello: 'world' });

    socket.on('nick', (data) => {
        // 处理昵称事件
        console.log(`Nick received: ${data.name}`);
    });

    socket.on('all', (data) => {
        // 广播消息
        socket.broadcast.emit('broad', { type: 0, msg: '信息推送', name: 'SYSTEM' });
    });

    socket.on('disconnect', () => {
        console.log('User disconnected');
    });
});

server.listen(6789, () => {
    console.log('Server is running on port 6789');
});
客户端代码

客户端代码需要确保通过正确的 URL 连接到服务端,并且使用 cors 参数来处理跨域请求。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Socket.IO Client</title>
</head>
<body>
<script src="http://x.x.x.x:6789/socket.io/socket.io.js"></script>
<script>
    var socket;

    window.onload = function() {
        socket = io('http://x.x.x.x:6789', {
            cors: {
                origin: '*'
            }
        });

        socket.on('news', function (data) {
            console.log(data);
            socket.emit('my other event', { my: 'data' });
        });
    }

    function send(msg) {
        socket.emit('nick', { 'name': msg });
    }
</script>
<button onclick="send('Alice')">Send Nickname</button>
</body>
</html>

解释

  1. 服务端

    • 使用 io.origins('*:*') 配置 CORS 策略,允许所有来源的所有端口访问。
    • 通过 io.on('connection', ...) 监听连接事件,处理客户端发送的消息和断开连接。
  2. 客户端

    • 通过 <script> 标签引入 Socket.IO 库。
    • 使用 io('http://x.x.x.x:6789', { cors: { origin: '*' } }) 连接服务端,配置 CORS 选项。

这样配置后,客户端应该能够正确地与服务端进行 WebSocket 通信,不会受到跨域限制的影响。


在一个服务器上都没问题

求教,是此路不通吗? 还是有办法解决

针对你提到的 Node.js Socket.IO 跨域问题,可以通过配置 CORS(跨源资源共享)来解决。Socket.IO 提供了相应的设置选项来处理这些情况。

服务端代码修改

首先,需要正确设置 CORS 选项。注意,io.set('origin', '*') 是旧版的用法,推荐使用 origins 方法来配置允许的源。以下是更新后的服务端代码:

var express = require('express');
var http = require('http');
var socketIo = require('socket.io');

// 创建 Express 应用和 HTTP 服务器
var app = express();
var server = http.createServer(app);

// 创建 Socket.IO 实例,并关联到 HTTP 服务器
var io = socketIo.listen(server);

// 配置 CORS 允许所有来源
io.origins('*:*');

io.sockets.on('connection', function(socket) {
    socket.emit('news', { hello: 'world' });

    socket.on('nick', function(data) {
        console.log('Nick received:', data.name);
        // 这里你可以添加你的数据库操作逻辑
    });

    socket.on('all', function(data) {
        socket.broadcast.emit('broad', {'type': 0, 'msg': '信息推送', 'name': 'SYSTEM'});
    });

    socket.on('disconnect', function() {
        console.log('Client disconnected');
        // 这里你可以添加断开连接时的清理逻辑
    });
});

// 启动服务器
server.listen(6789, function() {
    console.log('Server listening at port %d', 6789);
});

客户端代码保持不变

客户端代码不需要做任何更改。确保客户端 HTML 文件正确加载了 Socket.IO 的客户端库:

<script src="http://x.x.x.x:6789/socket.io/socket.io.js"></script>
<script>
    var socket;
    window.onload = function() {
        socket = io.connect('http://x.x.x.x:6789');
        socket.on('news', function(data) {
            console.log(data);
            socket.emit('my other event', { my: 'data' });
        });
    }

    function send(msg) {
        socket.emit('nick', {'name': msg});
    }
</script>

解释

  • CORS 配置:通过设置 io.origins('*:*'),我们允许所有来源和所有端口访问 Socket.IO 服务。这解决了跨域问题。
  • 日志输出:为了调试方便,添加了一些简单的日志输出,帮助确认客户端连接和服务端事件处理是否正常工作。
  • 其他部分:保持原有的业务逻辑不变,确保其他功能如消息广播等能够正常运行。

这样配置后,你应该不会再遇到跨域问题,客户端能够正常连接到服务端。

回到顶部