How do you get data from one domain to another using Javascript?
Recently I was asked to fetch data from one domain and use the data to update a website on another server. Let’s call these sites site1 and site2. The problem we faced was that site2 was a weblog powered by Blogger, which doesn’t allow a website owner to run any server side code. So we couldn’t use Java or Ruby or PHP. Instead, all we could use was Javascript.
My first thought was, “No problem! I’ll just do an Ajax call to get the data.” However, this does not work. The Javascript security model enforces a Same Origin Policy on Ajax. If you, with your web browser, go to site1, then the Javascript that your browser downloads can only make calls against site1. The Javascript can not make an Ajax call to site2.
Of course, when you look around the web, you see hundreds of sites that appear to be getting around this problem. For instance, all of the mashup sites that do interesting things with the Google APIs are clearing getting data from Google, somehow.
The answer is apparently what is known as the Script Tag Hack. The script tag is not effected by the Same Origin Policy. You can import data from somewhere else by putting this on your page:
<script src=”http://www.site1.com/neededInfo.php”></script>
In this example, the PHP script neededInfo.php (which is on site1) can output whatever info the Javascript on site2 needs to import. There are two tricks to make this work:
1.) The PHP script neededInfo.php (which is on site1) needs to wrap the data in a call to whatever Javascript function will be used on site2 to handle the data. So you might output the data like this:
updateComments({ ‘/93467763726066064′: ‘255′, ‘/3687512778221280499′:
‘154′, ‘/7469483397667998711′: ‘69′, ‘/3546694631903279790′: ‘86′, ‘/
7826626581502083668′: ‘257′, ‘/7863118590857837142′: ‘3′, ‘/
4528442172302293469′: ‘121′, ‘/4746505715184542507′: ‘125′, ‘/
3734446988393833799′: ‘242′, ‘/3855898527917724656′: ‘190′, ‘/
2322556671825296195′: ‘89′, ‘/7828790542573728707′: ‘83′, ‘/
7789277747613265886′: ‘137′, ‘/856477599963783632′: ‘109′, ‘/
170917561786384883′: ‘119′, ‘/2415194963852019364′: ‘66′, ‘/
4594614219998113399′: ‘106′, ‘/8621485541364545191′: ‘297′, ‘/
2546912594140426303′: ‘159′, ‘/2124986657277402452′: ‘284′, ‘/
294853826990957498′: ‘112′ })
This is all that should be on the page, just this, nothing else. Now updateComments() is the Javascript function that will be called on site2, when the script is imported. And the call to add in this script should happen only after the page is done loading. So when your browser downloads all the HTML from site2, a script tag is added to the page, which imports this from site1, and which calls the Javascript function updateComments, which is being handed a block of JSON info, which can be treated, inside of updateComments, as any other Javascript object.
2.) This needs to run after the page is done downloading. There are a number of good scripts for ensuring that something happens after the page is done downloading. I’ve often used Simon Willison’s script. Or, if a site is using jQuery, you can just register it as a function to run inside of the ready() method:
jQuery(document).ready(function() {
getSomeData();
});
Or you can just do things the simple way:
window.onload= function () {
getSomeData();
};
In the function getSomeData(), you’d then add a script tag to the page, using DOM methods:
var script= document.createElement(’script’);
script.type= “text/javascript”;
script.src=”http://www.site1.com/neededInfo.php”;
document.body.appendChild(script);
This is, apparently, the only way to get data from one domain to another, using Javascript.
I’m grateful to Jorge Chamorro for helping me understand this issue and for putting up an excellent example.