【问题标题】:Socket.io - Origin not allowed by Access-Control-Allow-OriginSocket.io - Access-Control-Allow-Origin 不允许的来源
【发布时间】:2013-01-20 06:51:47
【问题描述】:

我知道在 SO 上对此主题进行了一些讨论,但我找不到我的问题的答案。我在 localhost:8020 上使用 Aptana 在服务器上运行了一个网页。页面上的 javascript 正在访问我在 localhost:1337 上运行的节点服务器。这是节点代码:

var io = require('socket.io');
var http = require('http');
var sys = require('sys');
var json = [];
var server = http.createServer(function (req, res) {

  var headers = {};
  headers["Access-Control-Allow-Origin"] = "*";
  headers["Access-Control-Allow-Methods"] = "POST, GET, PUT, DELETE, OPTIONS";
  headers["Access-Control-Allow-Credentials"] = true;
  headers["Access-Control-Max-Age"] = '86400'; // 24 hours
  headers["Access-Control-Allow-Headers"] = "X-Requested-With, Access-Control-Allow-Origin, X-HTTP-Method-Override, Content-Type, Authorization, Accept";
  res.writeHead(200, headers);
  res.end();
});
server.listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');
var socket = io.listen(server);
socket.on('connection', function(){
  console.log("Connected");
});

我通过更改标头来处理 cors 请求,我一直这样做。我的客户端代码通常是 socket.io 初学者的东西。这是我的代码中的标签:

<script src="http://cdn.socket.io/stable/socket.io.js"></script>
    <script>

        // Create SocketIO instance
        var socket = new io.Socket('localhost',{
            port: 1337
        });
        socket.connect();

        // Add a connect listener
        socket.on('connect',function() {
            log('<span style="color:green;">Client has connected to the server!</span>');
        });
        // Add a connect listener
        socket.on('message',function(data) {
            log('Received a message from the server:  ' + data);
        });
        // Add a disconnect listener
        socket.on('disconnect',function() {
            log('<span style="color:red;">The client has disconnected!</span>');
        });

        // Sends a message to the server via sockets
        function sendMessageToServer(message) {
            socket.send(message);
            log('<span style="color:#888">Sending "' + message + '" to the server!</span>');
        }

        // Outputs to console and list
        function log(message) {
            var li = document.createElement('li');
            li.innerHTML = message;
            document.getElementById('message-list').appendChild(li);
        }

当我运行代码时,我不断收到“XMLHTTPRequest...Origin is not allowed by Access-Control-Allow-Origin”错误。我的浏览器是chrome。 1. 为什么我的浏览器使用的是 XMLHTTPRequest 而不是 Websocket? 2. 为什么我在更改标题时收到访问控制错误? 感谢您提前提供的所有帮助。

【问题讨论】:

  • 我一直面临同样的问题,这让我抓狂。你能找到解决方案吗?
  • 我确实想通了,我需要发布完整的答案,但已经有一段时间了,我需要看看我做了什么。给我一些关于你的具体问题的更多细节。
  • 我也遇到了这个问题,很想听听您的解决方案。我想出的唯一解决方案并不理想,因为它涉及破解 socket.io 库中的“manager.js”代码以更改它声明 headers['Access-Control-Allow-Origin'] = ' 的行*';必须有更好的方法......

标签: javascript node.js socket.io cors


【解决方案1】:

根据 socket.io 文档,您应该能够设置传输的优先级(如果它产生问题,可能会跳过一个)并直接配置 socket.io 来源。

io.set('transports', ['websocket', 'xhr-polling', 'jsonp-polling', 'htmlfile', 'flashsocket']);
io.set('origins', '*:*');

【讨论】:

    【解决方案2】:

    您的自定义标头实际上永远不会为与 socket.io 相关的请求编写。

    Socket.IO 覆盖了 http 服务器的一些方法。其中之一是触发“请求”处理程序。 Socket.IO 只允许自己成为所有请求的主要处理程序。然后它会测试请求是否真的是 socket.io 请求(基于请求的路径的前缀)。如果它确定它不应该处理给定的请求,它会触发其他“请求”处理程序。

    您只需在 writeHead 调用之前添加一个 console.log 语句即可看到这一点,您会看到 stdout 中没有任何内容。

    读取source code,似乎socket.io自动设置了一个Access-Control-Allow-Origin标头,其值为请求的origin标头。我认为也有一种方法可以在客户端上设置这样的标头。

    所以,澄清一下:

    1您的浏览器回退到 xhr-polling,因为它不支持 websocket 或 websocket 传输静默失败

    2 您在 httpServer request 事件中设置的标头永远不会被发送,因此它们对源策略没有任何操作。

    解决方案:想办法在请求中设置origin 标头。在浏览完客户端代码后,我没有发现任何证据表明这可以轻松完成。

    【讨论】:

      【解决方案3】:

      需要注意的是,当 Access-Control-Allow-Credentials 为 true 时,不能在 Access-Control-Allow-Origin 标头中使用“*”值。删除 Access-Control-Allow-Credentials 标头,或将 Access-Control-Allow-Origin 设置为请求 Origin 标头的值。

      【讨论】:

        猜你喜欢
        • 2013-02-05
        • 2011-10-27
        • 2012-08-10
        • 1970-01-01
        相关资源
        最近更新 更多