Search code examples
ajaxhttp-headersxmlhttprequestcross-domainfirefox-9

(firefox 9) javascript ajax to an external domain, status 0 but LiveHTTP Headers capture the correct answers (!?)


I am trying to do an AJAX call to an external domain. After reading a little bit, I have realised that this cannot be done. And I was starting to dive into proxys solution, but then I've found info about "cross-site xmlhttprequest with CORS"

Then, from here I have understood that perhaps non-old browsers had already implemented a way to do it, as far as the target domain allowed it I guess.

So, within this obscurity, I have decided to check the HTTP headers that were being captured.

It is a GET petition

http://www.genome.jp/dbget-bin/www_bconv?dbkey=uniprot&acc=P11730

Using any broswer I get the web page that I want, but through the AJAX call I get an status of 0.

But, with the AJAX script and using the firefox add-on Live HTTP headers, I can see that everything seems to go all right

http://www.genome.jp/dbget-bin/www_bconv?dbkey=uniprot&acc=P62071

GET /dbget-bin/www_bconv?dbkey=uniprot&acc=P62071 HTTP/1.1
Host: www.genome.jp
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:9.0.1) Gecko/20100101 Firefox/9.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Origin: null

HTTP/1.1 302 Found
Date: Sat, 28 Jan 2012 19:24:24 GMT
Server: Apache
Location: /dbget-bin/www_bget?mmu:66922
Content-Length: 0
Keep-Alive: timeout=60, max=1000
Connection: Keep-Alive
Content-Type: text/plain

So, there are 2 options:

1) it is working, but the code has some kind of error

2) It seems to be working, but actually AJAX cannot be done to an external domain. Why Live HTTP headers is capturing the good stuff? because the censorship is done afterwards.

What is the answer?

(javascript code)

    <html>
    <head>
    <script type="text/javascript">
    function loadXMLDoc()
    {
    var xmlhttp;
    xmlhttp=new XMLHttpRequest();

    xmlhttp.onreadystatechange=function()
    {
    alert(xmlhttp.readyState+'  '+xmlhttp.status)
    if (xmlhttp.readyState==4)
    {
    alert(xmlhttp.responseText);
    }
    }

    if("withCredentials" in xmlhttp)
    {
    xmlhttp.open("GET","http://www.genome.jp/dbget-bin/www_bconv?dbkey=uniprot&acc=P11730",true);
    xmlhttp.withCredentials = "true";
    xmlhttp.onreadystatechange = handler;
    xmlhttp.send();
    }

    }
    </script>
    </head>
    <body>

EDIT: So it is like that to use CORS the extra header needs to be enabled on the web server. Then I assume it is option 2).

Interesting links

Ways to circumvent the same-origin policy

http://anyorigin.com/

http://enable-cors.org/

http://remysharp.com/2011/04/21/getting-cors-working/


Solution

  • Your assumptions are correct.

    Contrary to popular belief, an XMLHttp request to an external domain can always be sent. But, javascript does not grant access to the response document.

    This is due to the Same Origin Policy

    The same origin policy prevents a document or script loaded from one origin from getting or setting properties of a document from another origin.

    As you found out, if the server agrees to grant access by setting an according header, this restriction does not apply (provided the browser supports CORS too).