It is likely that you have already used or have heard of AJAX. The ubiquitous example is Google Maps, which certainly wasn’t the first but is arguably the most quoted.
AJAX is a very useful technology but have you ever tried to use it across domains? For example, try to send an AJAX request from www.yoursite1.com to www.yoursite2.com. Does it work? Let me save you some time and tell you the answer is no. It won’t work by design. The Javascript specification considers cross-domain XMLHttpRequests to be a security risk, which it can be.
So, what if you have a legitimate business requirement to do cross-domain Javascript requests? The most important reason I can think of for this requirement is a third-party service, or web systems that are distributed across domains. There are many of these types of instances where cross-domain AJAX would be very valuable.
You could require the browser to download a Java applet, which would immediately alienate some browsers. You could use a Flash solution but again, many people simply won’t take the time to download the applet or plugin. More importantly for tracking services, sending Flash or Java applications to browsers on every request is simply not going to scale.
Enter Asynchronous Javascript Across Domains. How does it work?
- Javascript can dynamically generate or load more Javascript.
- Javascript can be loaded across domains.
Is the light going on yet?
So, we write some Javascript that will dynamically append a script tag
Lets look at an example:
Let’s say we track referrers for our client sites. One of our clients is webtalon.com. So webtalon.com places our JS tag onto all of their pages and it looks like this:
… which spits back some code, generated on the server side, that looks something like this:
var ajad_url = 'http://bombast.cblackburn.com/';
var ajad_ndx_script = 0;
function ajad_do (u) {
// Check that we have prepended the ajad_url
if (u.substring(0, 4) != 'http') {
u = ajad_url + u;
}
// Create new JS element
var js = document.createElement('SCRIPT');
js.type = 'text/javascript';
ajad_ndx_script++;
js.id = 'ajad-' + ajad_ndx_script;
js.src = u;
// Append JS element (therefore executing the 'AJAX' call)
document.body.appendChild(js);
return true;
}
function ajad_get (r) {
// Create URL
var u = ajad_url + 'track_refer.php?r=' + escape(r) +
'&id=1247';
// Do AJAD
return ajad_do(u);
}
function ajad_send() {
// referrer
r = window.location;
// send it
ajad_get(r);
// remove the last script node.
document.body.removeChild(document.getElementById('ajad-' + ajad_ndx_script));
ajad_ndx_script--;
}
ajad_send();So what happens here? The browser loads this Javascript and calls ajad_send(). Let’s look at the ajad_send() function:
The first thing we do is to grab the referrer from the browser.
// referrer
r = window.location;This works even in Macintosh browsers as long as Javascript is turned on. Today, if someone turns off Javascript in their browser much of the web simply won’t work. So the chances they have Javascript turned on are big.
Next we call ajad_get(), passing the referrer we just collected. ajad_get is so named because we are ‘getting’ more Javascript. This call passes control to another function which actually appends a Javascript node to the browser document.
// send it
ajad_get(r);We’ll examine ajad_get() in a bit…
Lastly we remove the Javascript that was just appended. We want to keep the page clean of Javascript that we are finished using.
// remove the last script node.
document.body.removeChild(document.getElementById('ajad-' + ajad_ndx_script));
ajad_ndx_script--;Ok, so lets look at what ajad_get() does…
// Create URL
var u = ajad_url + 'track_refer.php?r=' + escape(r) +
'&id=1247';
// Do AJAD
return ajad_do(u);…not much. Here we simply build the URL which will serve two purposes:
- Pass the referrer back to the server script track_refer.php at bombast.cblackburn.com.
- Retrieve more Javascript, if necessary, to make additional AJAD calls.
Next we call ajad_do(), passing the URL we just built.
// Check that we have prepended the ajad_url
if (u.substring(0, 4) != 'http') {
u = ajad_url + u;
}
// Create new JS element
var js = document.createElement('SCRIPT');
js.type = 'text/javascript';
ajad_ndx_script++;
js.id = 'ajad-' + ajad_ndx_script;
js.src = u;
// Append JS element (therefore executing the 'AJAX' call)
document.body.appendChild(js);
return true;Ahhh, so here is where the real work takes place.
First we double-check that the calling function passed in a URL with ‘http’ prepended. In our case we have, so it should not be necessary, but double-checks are always a good idea.
Then we create a new script tag, set its type to ‘text/javascript’, increment our node counter, assign an ID to the node so we can remove it in the ajad_send() function, which we already examined, finally we assign the src attribute to the Javascript node.
Last thing is to append the node to the document.body and return true. This actually makes the AJAD request back to the server which looks something like this:
http://bombast.cblackburn.com/track_refer.php?r=https%3A//www.dmoz.org/
So back at the server side, we have a script ‘track_refer.php’ that processes the 'r=https%3A//www.dmoz.org/'. We tie that back to our client ‘webtalon.com’ using the ‘id=1247’.
Although we don't demonstrate it here, it is easy to see how the Javascript that we return from ‘track_refer.php’ could setup another call using AJAD, and so on, ad infinitum.
If you have any questions, as always, drop a comment below. I'm always interested to hear what new and improved things people are doing with code or ideas presented here.

