Socket.io + Express CORS Error on localhost (not allowed by Access-Control-Allow-Origin)

I have a working node.js Express server to which I would to add socket.io support (allow javascript clients to connect via socket.io). I can connect to the express server via a Javascript $.get(), but the socket.io.connect() command fails due to a CORS error.

My testing machine is OSX with Apache to serve the client, thus port 80 is taken, so I have node.js/express running on port 8888. I added socket.io per the documentation:

var exp = express();
var server = require('http').createServer(api.server);
exp.listen(8888);

var io = require('socket.io').listen(server);
io.sockets.on('connection', function(socket) {
     console.log('connection'); 
});

I properly see "info: socket.io started" in my node.js logs.

Then, on the client, I attempt to connect to the server...

    this.socket = io.connect('http://localhost:8888');
    this.socket.on('connect',function() {
        socket.emit('install','test');
    });

However, I'm getting a CORS error in the console in Chrome:

XMLHttpRequest cannot load http://localhost:8888/socket.io/1/?t=1358715637192. Origin http://localhost is not allowed by Access-Control-Allow-Origin.

HOWEVER, THIS works fine!

    $.get('http://localhost:8888',function(e,d){
        console.log(e,d); 
    });

So I double checked my headers, for both localhost:8888 and localhost -- both are properly returning the headers which (should) allow for the cross-domain requests...

Access-Control-Allow-Origin: *

enter image description here

Any ideas?

CORS is a very tricking thing to get working (or at least it was for me). I recommend this resource here: http://enable-cors.org/

Following what they do very carefully helped me. I also found that different browsers gave different visibility over the CORS request/responses which helped.

I found that Chrome was easier to get working than firefox, but firefoxes tools such as firebug, were quite nice to work with.

My gut feel from your information is that you might need your request to have an X-Request-With in your request attributes.

I also found using fidler to send the http requests allowed me to narrow my problems down to the server side initially and get that working. You will find browser enforce CORS, but something like fidler doesn't and thus provides another way of inspecting what is happening.

I definately recommend trying to break the problem in half so that you can see if it is server side or client side that is not behaving how you expect.

My problem was related to returning the same CORS response for the OPTIONS header as the POST or GET. That was wrong. Chrome allowed it. Firefox didnt. Any options request that is sent out will be sent out once, then in the future it will be cached and not resent (Which caused alot of confusion for me initially). For the options request you just need a standard response saying its ok to proceed, then in the post or get response i believe you want your cors responses there only.