繁体   English   中英

Socket.io-Access-Control-Allow-Origin不允许的来源

[英]Socket.io - Origin not allowed by Access-Control-Allow-Origin

我知道有人在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);
        }

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

根据socket.io文档,您应该能够同时设置传输的优先级(如果出现问题,则可以跳过传输优先级)并直接配置socket.io的来源。

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

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

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

通过将console.log语句放在writeHead调用之前,您可以看到这一点,并且您不会在stdout中看到任何内容。

阅读源代码后 ,似乎socket.io会自动使用请求的origin标头的值设置Access-Control-Allow-Origin标头。 我假设还有一种在客户端上设置此类标头的方法。

因此,要清除问题:

1您的浏览器因不支持websocket或websocket传输默默失败而回到了xhr-polling

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

解决方案:找到一种在请求上设置origin标头的方法。 在浏览了客户端代码之后,我发现没有证据表明可以轻松完成此操作。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM