Same-origin policy workaround using document.domain in Javascript

Rubix picture Rubix · Mar 8, 2010 · Viewed 38.4k times · Source

I am running into same-origin policy issues in Javascript. I've read about a workaround for this using the document.domain variable, but I cannot get the workaround to work. The workaround is that you are supposed to be able to set document.domain to 'example.com' so that if you run code from foo.example.com it can load data via XHR from bar.example.com.

Details on the workaround are here:

https://developer.mozilla.org/En/Same_origin_policy_for_JavaScript

My example code -- which doesn't produce the desired results -- is run from a URL like http://foo.example.com/:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<script>
document.domain = 'example.com';
window.onload = function() {
    var req = new XMLHttpRequest();
    var url = 'http://bar.example.com/';
    req.open('GET', url, true);
    req.onreadystatechange = function (aEvt) {
        if (req.readyState == 4) {
            var elem = document.getElementById('result');
            if (req.status == 200) {
                var data = req.responseText;
            } else {
                var data = "Error loading page: " + req.status;
            }
            elem.innerHTML = data;
        }
    };
    req.send(null);
};
</script>
Result:<hr>
<div id="result"></div>
</body>
</html>

The output from this code:

Result:
Error loading page: 0

If I change url to 'http://foo.example.com/', everything works correctly. Is there a bug in my example code?

I don't want to use a proxy because they're slower, less efficient, and will increase traffic on our web server. It'd be really cool if this workaround actually worked. Is this workaround "pie in the sky"?

Answer

Mic picture Mic · Mar 9, 2010

document.domain allows the communication between frames/iframes. Not XHR.

<body>
<iframe src="http://bar.example.com/"></iframe>
<script>
    document.domain = 'example.com';
    var ifr = document.getElementsByTagName('IFRAME')[0];
    ifr.onload = function(e){
        //will log the string "BODY" in the console
        console.log(ifr.contentWindow.document.body.tagName);
    };
</script>
</body>

If you remove the line with document.domain, reading the content of the contentWindow will throw the Same Origin Policy error.