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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14705941/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 22:21:46  来源:igfitidea点击:

Socket.io - Origin not allowed by Access-Control-Allow-Origin

javascriptnode.jssocket.iocors

提问by jhamm

I know there has been some discussion on this topic on SO, but I cant find the answer to my question. I have a web page running on the server with Aptana on localhost:8020. The javascript on the page is hitting a node server I have running on localhost:1337. Here is the node code:

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

I am handling the cors request by changing the headers, which I do all the time. My client side code is typically socket.io beginner stuff. Here is the tag from my code:

我通过更改标头来处理 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);
        }

When I run the code I keep getting 'XMLHTTPRequest...Origin is not allowed by Access-Control-Allow-Origin' errors. My browser is chrome. 1. Why is my browser using XMLHTTPRequest and not a Websocket? 2. Why am I getting a Access control error when I am changing the headers? Thanks for all the help in advance.

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

回答by jornare

According to socket.io documentation, you should be able to set both priority of the transports (and maybe skipping one if it creates problems) and configure socket.io origins directly.

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

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

回答by Floby

Your custom headers actually never get written for socket.io related requests.

您的自定义标头实际上从未为 socket.io 相关请求编写。

Socket.IO overrides some methods of the http server. One of them is the triggering of the 'request' handlers. Socket.IO only allows itself to be the primary handler of all requests. Then it tests if the request is actually a socket.io request (based on the prefix of the path requested). If it determines that it shouldn't handle a given request, it triggers other 'request' handlers.

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

You can see that by just putting a console.log statement before your writeHead call and you'll see that nothing appears in stdout.

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

Reading the source code, it seems that socket.io automatically sets a Access-Control-Allow-Originheader with the value of the originheader of the request. I would assume there is a way to set such a header on the client as well.

读取源代码,似乎socket.io自动设置一个Access-Control-Allow-Origin与所述的头值origin的请求的报头中。我认为也有一种方法可以在客户端上设置这样的标头。

So, to clear things up:

所以,要弄清楚:

1Your browser falsl back to xhr-polling because it doesn't support websockets or websocket transport fails silently

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

2The headers you set yourself in the httpServer requestevent never get sent, so they have no action on the origin Policy.

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

solution:find a way to set the originheader on the request. After crawling throught the client code, I have found no evidence that this can be done easily.

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

回答by monsur

One thing to note is that the '*' value cannot be used in the Access-Control-Allow-Origin header when Access-Control-Allow-Credentials is true. Either remove the Access-Control-Allow-Credentials header, or set Access-Control-Allow-Origin to the value of the request Origin header.

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