Alternative Cross-Origin Resource Sharing (CORS) Techniques

My first encounter with Cross-Domain Request was when I was creating the UK football league stats table. My first approach was to download the data in a csv file and load it from my server. However, I discovered that it would be inefficient to keep replacing the file with the most recent data after each update (i.e. there are matches played at least once/week). I looked into ways I could easily query the data automatically from the source itself. I tried using AJAX but I had some CORS limitations. In short, the csv file source domain did not allow anyone (specifically any website) to query their data. In the end, I ended up just using a server side solution (which is probably not legal). I was inspired from then to research1 several ways one can implement CORS in different scenarios. Below is a sample of ways one can implement this technique.

Image Ping:

This works for GET requests. You won’t be able to read the response text. However, it’s a good way to make sure the target server receives a notification from the origin page. From what I’ve learnt, it is one of the ways ads can track their views. You can also track user-clicks (or general interaction) without unnecessary interruption.

var imgCORS = new Image();
imgCORS.onload = imgCORS.onerror = function(){ 
 console.log("Done & Dusted");
};
//we assign both onload and error the same fn to ensure we capture both responses from the server
imgCORS.src = "http://www.example.com/track?clickedLink=3";

Script tags with JSON Padding (JSONP):

JSONP uses the script tags to communicate with other domains. It has a leg over the Image ping due its ability to read requests. To summarize JSONP, you create a script tag, you assign the source in a special formatted way, and finally you use a callback to read the response. Things to keep in mind:

  • The target source has to be ready to process your request
  • The requester is at the mercy of the target source because the callback will be executing whatever the target source sends back.
  • There is no defined method to process errors due to lack of error handling in browsers (setTimeout can be used but it would be assuming the same connection speed on each user)
function handleResponse(response){
  console.log("Your name is  " + response.name + ", and you're " + response.age + " years old.");
}
var script = document.createElement("script");
script.src = "http://example.com/json/?callback=handleResponse";
document.body.insertBefore(script, document.body.firstChild);

Comet/Long Polling:

I have to admit that I’ve never used comet, long-polling, or any form of server-push. My understanding is from a purely theoretical view. Feel free to correct me if need be. To explain it, comet/long-polling is using the server to push data instead of AJAX requesting data. This way you get a real-time response from the server (think sports scores/twitter updates). Short polling involves the browser requesting the server at regular intervals but long-polling reverses the process and holds the gates open (so to speak) until it has something to send. To summarize:

  1. Browser opens up a request
  2. Server holds the gates open until it has something to send back
  3. Browser receives the response from server and closes the request
  4. Browser immediately goes back to #1
function createStream(url, progress, finished){ 

  var xhr = new XMLHttpRequest(),
  received = 0;

  xhr.open("get", url, true);
  xhr.onreadystatechange = function(){
   var result;

   if (xhr.readyState == 3){

     //get only the new data and adjust counter
     result = xhr.responseText.substring(received); //read from last end-point
     received += result.length;

     //call the progress callback
     progress(result);

   } else if (xhr.readyState == 4){
     finished(xhr.responseText);
   }
  };
  xhr.send(null);
  return xhr;
  }
  var client = createStream("/streaming", function(data){
   console.log("Received: "+ data);
  }, function(data){
   alert("Done!");
  });

Server-Sent Events (SSE):

SSE is an API for read-only Comet requests. It supports short-polling, long-polling & HTTP streaming. That’s as far as my knowledge of it goes. Read up more about the API here

Web Sockets:

There’s far too much that has been written about Web Sockets. In short, Web Sockets are better versions of comet/long-polling. You should keep in mind that Web Sockets don’t operate on the standard http (hence ws://example.com). So, how does it work exactly? I can verify that it is all magic!

1. [Majority of this information (and code) was obtained from Nicholas Zakas’ Professional JavaScript for Web Developers. The rest I tried to link to the original sources. Let me know if I missed anything!]

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s