views:

1004

answers:

3

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"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"&gt;
<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"?

Thanks.

+3  A: 

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

<body>
<iframe src="http://bar.example.com/"&gt;&lt;/iframe&gt;
<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.

Mic
Thanks Mic, it's good to know how document.domain can be used correctly.
Rubix561
+1  A: 

Since Mic answered why it doesn't work, I thought I'd share the solution to "how" to make cross-domain work. See my SO post here.

j0rd4n
Thank j0rd4n, this is exactly the sort of non-proxy solution I was looking for, even if I was barking up the wrong tree with document.domain. I found a bit more info on the scheme they call JSONP and how jQuery has this functionality built in too, which is outside the scope of my question, but interesting nonetheless:http://www.ibm.com/developerworks/library/wa-aj-jsonp1/
Rubix561
The process I mentioned uses JSONP but it does it in a manual sense. jquery will handle the "receiving" of the JSONP into the javascript DOM, but you still have to provide a service that returns the JSONP text. At the end of the day, your server page must return formatted JSONP. Your JavaScript (whether it be jquery, ext-js, etc.) must make the call to run the script inside of a script tag.
j0rd4n
A: 

It seems this [ http://consumer.easyxdm.net/current/example/xhr.html ] example of how to use easyXDM would do the trick as well.

Sean Kinsey