我知道在SO上有关于这个主题的讨论,但是我找不到我的问题的答案。我在本地主机上使用Aptana在服务器上运行了一个网页:8020。页面上的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 ...来自Access-Control-Allow-Origin'的错误。我的浏览器是chrome。 1.为什么我的浏览器使用XMLHTTPRequest而不是Websocket? 2.当我更改标题时,为什么会出现访问控制错误? 在此先感谢您的所有帮助。
答案 0 :(得分:3)
根据socket.io文档,您应该能够设置传输的优先级(如果它产生问题,可能会跳过一个)并直接配置socket.io origin。
io.set('transports', ['websocket', 'xhr-polling', 'jsonp-polling', 'htmlfile', 'flashsocket']);
io.set('origins', '*:*');
答案 1 :(得分: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,因为它不支持websockets或者websocket传输无声地失败
2 您自己在httpServer request
事件中设置的标头永远不会被发送,因此他们对原始政策没有任何操作。
解决方案:找到一种在请求中设置origin
标头的方法。在抓取客户端代码后,我没有发现可以轻松完成此操作的证据。
答案 2 :(得分:1)
需要注意的一点是,当Access-Control-Allow-Credentials为true时,不能在Access-Control-Allow-Origin标头中使用'*'值。删除Access-Control-Allow-Credentials标头,或将Access-Control-Allow-Origin设置为请求Origin标头的值。