When I try to use Socket.IO with PhoneGap I get this error:

(on iOS where socket.io should be supported)

Origin null is not allowed by Access-Control-Allow-Origin.

This is because my app is served via file:// protocol. What can I do to get around this?

Thanks!!


Solution 1:

You have to add the socketio host to the "ExternalHosts" key in PhoneGap.plist.

See Faq:

Q. Links to and imported files from external hosts don't load?

A. The latest code has the new white-list feature. If you are referencing external hosts, you will have to add the host in PhoneGap.plist under the "ExternalHosts" key. Wildcards are ok. So if you are connecting to "http://phonegap.com", you have to add "phonegap.com" to the list (or use the wildcard "*.phonegap.com" which will match subdomains as well). (Note: If you open the plist file in Xcode, you won't need to fiddle with the XML syntax.)

For android you have to edit cordova.xml and add access to the socketio host:

<access origin="HOST*"/> 

index.html (with socketio example):

...
<script src="HOST/socket.io/socket.io.js"></script>
<script>
    var socket = io.connect('HOST');
    socket.on('news', function (data) {
        socket.emit('my other event', { my: 'data' });
    });
</script>
...

app.js (server side javascript / basic socketio example):

var io = require('socket.io').listen(80);

io.sockets.on('connection', function (socket) {

socket.emit('news', { hello: 'world' });
    socket.on('my other event', function (data) {
        console.log(data);
    });
});

The HOST you have to replace with hostname of your socket.io server!

Solution 2:

Using PhoneGap the webpage is opened using the file:// protocol

With file:// protocol no origin is set to the WebSocket connection, so the browser will raise that security exception if the server doesn't set the Access-Control-Allow-Origin header to the response enabling CORS

Consider using some PhoneGap plugin like the following, which uses native code to handle the connection, but enables a (hopefully standard-compatible) WebSocket API inside the webviews

Android: https://github.com/anismiles/websocket-android-phonegap

iPhone: https://github.com/remy/PhoneGap-Plugin-WebSocket

Those plugins are just the first ones I found, not sure how much they are actively developed and stable

Solution 3:

So if the webpage opened with the file:// url protocol in PhoneGap was to send the header "Access-Control-Allow-Origin: *" -- theoretically it should all work with socket.io?

(it's possible to do so through NSURLProtocol, but I didn't want to go down this rabbit hole without knowing the fix)