The new way to do Cross Domain Ajax/Comet: Cross-Origin Resource Sharing

Wedoist Comet

Wedoist features a realtime system that's powered by comet where the state is synced across all open sessions. Today we have rewritten our client side implementation to use Cross-Origin Resource Sharing, which is a relatively new technology to do cross domain communication. This technology is supported by following browsers:

  • Firefox 3.5+
  • Safari 4+
  • Google Chrome 3+
  • Internet Explore 8+

Implementing comet is a challenge, both on the backend and the client side. In this blog post I will only feature the client side implementation.

How is our comet setup?

comet0X.wedoist.com points to a nginx server that proxies to JBoss Netty servers. This makes it possible to support SSL and load balance.

This solution scales really well, but we need to do cross-domain requests to comet0X.wedoist.com. For this we used ScriptCommunicator, which is one of my more popular open-source projects. It basically uses script tags for communication and it resolves to hacks in order to detect errors.

Using Cross-Origin Resource Sharing

The main points of Cross-Origin Resource Sharing are following:

  • Your backend server specifies which origins it accepts requests from via a special Access-Control-Allow-Origin header
  • On Chrome, Safari of Firefox you use XMLHttpRequest object and check for withCredentials property
  • On Internet Explorer 8+ you use XDomainRequest object
  • For everything else you resolve back to script tags

Our implementation of this strategy is shared below.

Specifying Access-Control-Allow-Origin

You need to specify what origins you are accepting requests from and you do this by adding a special Access-Control-Allow-Origin header.

In nginx you can do following to only accept from https://wedoist.com;

location / {
    add_header Access-Control-Allow-Origin https://wedoist.com;
    proxy_pass http://0.0.0.0:8001/;
}

To accept from everywhere you would do this (it isn't recommended to due CSRF exploits!):

location / {
    add_header Access-Control-Allow-Origin *;
    proxy_pass http://0.0.0.0:8001/;
}

Implementation of the new script communicator

You can download and fork the code here:
https://github.com/amix/Script...

Using the new script communicator

To use the new script communicator simply do following:

var url = 'http://some_domain.com/give_me_js_back.php?i=42&callback=foocall'
ScriptCommunicator.sourceJavascript(url, on_success, on_error)

on_success and on_error are functions. on_error is only supported by browser that support Cross-Origin Resource Sharing, i.e.:

  • Firefox 3.5+
  • Safari 4+
  • Google Chrome 3+
  • Internet Explore 8+

Like the old ScriptCommunicator implementation your server should return JavaScript that can be eval'ed.

References

© Amir Salihefendic