Cross domain requests (also known as Cross Origin Resource Sharing) can be made using JavaScript without trickery, as far as I can tell, in Firefox 3.5, Safari, Google Chrome and Internet Explorer 8. This is done with all browsers except IE8 using a standard XMLHttpRequest object. The only thing required to notify the browser that JavaScript is allowed to make this request is for the server to send a Access-Control-Allow-Origin response header. Internet Explorer 8 uses an object called XDomainRequest and requires the same HTTP header. If the value of the header is * then requests are allowed from all domains. You can be more restrictive if required.

I took the code that I’ll use below from this CORS in action page but I couldn’t find the code required to make this work in Internet Explorer so I’ve had to modify things a bit.

See it in action

The information below (when it appears) has been fetched using cross-site XHR.

The code

<script type="text/javascript">

        var isIE8 = window.XDomainRequest ? true : false;
        var invocation = createCrossDomainRequest();
        var url = 'http://www.phobos7.co.uk/research/xss/simple.php';        

        function createCrossDomainRequest(url, handler)
        {
            var request;
            if (isIE8)
            {
                request = new window.XDomainRequest();
            }
            else
            {
                request = new XMLHttpRequest();
            }
            return request;
        }

        function callOtherDomain()
        {
            if (invocation)
            {
                if(isIE8)
                {
                    invocation.onload = outputResult;
                    invocation.open("GET", url, true);
                    invocation.send();
                }
                else
                {
                    invocation.open('GET', url, true);
                    invocation.onreadystatechange = handler;
                    invocation.send();
                }
            }
            else
            {
                var text = "No Invocation TookPlace At All";
                var textNode = document.createTextNode(text);
                var textDiv = document.getElementById("textDiv");
                textDiv.appendChild(textNode);
            }
        }
        
        function handler(evtXHR)
        {
            if (invocation.readyState == 4)
            {
                if (invocation.status == 200)
                {
                    outputResult();
                }
                else
                {
                    alert("Invocation Errors Occured");
                }
            }
        }

        function outputResult()
        {
            var response = invocation.responseText;
            var textDiv = document.getElementById("textDiv");
            textDiv.innerHTML += response;
        }
    </script>

    <form id="controlsToInvoke" action="">
        <p>
            <input type="button" value="Click to Invoke Another Site" onclick="callOtherDomain()" />
        </p>
    </form>
 
    <div id="textDiv">
        The information below (when it appears) has been fetched using cross-site XHR.
    </div>

And this is the code on the server

<?php
	header('Content-type: text/html');
    header('Access-Control-Allow-Origin: *');
	$uri = 'http'. ($_SERVER['HTTPS'] ? 's' : null) .'://'. $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
	echo('<p>This information has come from <a href="' . $uri . '">' . $uri . '</a></p>');
?>
Share →
Buffer
  • adam

    Now use mime multipart replace, and you’re all set for streaming (in everything except IE)

  • Pingback: Using Fidder to help develop cross domain capable JavaScript web applications | Phil Leggetter - Software Consultant

  • alexpolo

    On Opera, security violation trying to “See it in action”.

  • wade

    XDomainRequest – Restrictions, Limitations and Workarounds
    The XDomainRequest is so limited as to be almost useless.  Essentially it can only be used for unauthenticated GET/POST and in the case of POST server side hacks must be used because their implementation is admittedly broken.  I would advise using a Flash based alternative like flXHR for all versions of IE.

  • Pingback: Client Push Services Open Up Real-Time to Everyone

  • Pingback: Client Push Services Open Up Real-Time to Everyone | Phil Leggetter - Software Consultant

  • Google

    cool man

  • Prateek89born

    broken in opera :(
    wht to do nw???

  • Rajani

    I am using Chrome 18.0.1025.152 m to load a jsp page using tomcat and from that jsp I am making a https request to another server and I am getting 
    XMLHttpRequest cannot load https://remote-host:8443/TWPersonalAgentSvc/personalagent. Origin https://localhost:8443 is not allowed by Access-Control-Allow-Origin.
    I am using the code above.

    • http://www.leggetter.co.uk Phil Leggetter

      It sounds like your Access-Control-Allow-Origin header isn’t being set by the server or it would be allowed by the browser. Which browser are you using?

  • Ersanbilik

    does this work with https protocol ? 

    • http://www.leggetter.co.uk Phil Leggetter

      Yep. There may be cross scheme restrictions e.g. http -> https connections.

  • Pingback: Same origin policy and Cross Domain Requests. « TechStadium.in

  • Christian

    Very helpful. solved my problem.  Thanks a lot!

  • http://cawoodm.wordpress.com/ Marc

    Why do do you not have a invocation.onreadystatechange for isIE8 in callOtherDomain?

    • http://www.leggetter.co.uk Phil Leggetter

      It’s been so long since I wrote this I don’t know definitively. Simply looks like the `onload` fires in IE8 and `onreadystatechange` is used for other browsers.

      • http://cawoodm.wordpress.com/ Marc

        Yep, that’s it. What a drag :-)

  • Abhilash

    Nothing is working in IE8

    • johndurbinn

      Pretty much. Welcome to IE.

  • Ricardo

    not work sorry

  • Kris

    Awesome…thanks for the example

  • Oluwasegun Ogidan

    How and where can one add the (<?php

    header('Content-type: text/html');

    header('Access-Control-Allow-Origin: *');

    $uri = 'http'. ($_SERVER['HTTPS'] ? 's' : null) .'://'. $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];

    echo('This information has come from ‘ . $uri . ‘‘);

    ?>)

    to the server side?

  • rado

    hi! tried to male cross domain request such type and get an error – invocation.status is zero.
    what’s can be the problem?

  • rado

    hi! I’m getting invocation.status 0 with request to any page. How can I make the request?

  • Elvis

    I am making a https request to another server but I get origin IP is not allowed by Access-Control-Allow-Origin with the code above.

    I tried setRequestHeader(“Access-Control-Allow-Origin” , “*”) still it doesn’t work. any suggestion Please?

    • http://www.leggetter.co.uk/ Phil Leggetter

      The header needs to be provided by the server. It’s not a client thing. If you can’t make the change to the server then it’s out of your control.

      However, you could use a service like http://www.corsproxy.com/ to work around this. It will proxy the request for you.

      • tarkan_

        Exactly what I was looking for, thanks ! :D
        Do you know any other crosproxys that work like this one?

        • http://www.leggetter.co.uk/ Phil Leggetter

          Apparently http://runscope.com offer similar functionality.

Realtime Web Apps: With HTML5 WebSocket, PHP, and jQuery

Buy the book I co-write with Jason Lengstorf via Amazon.com or Amazon.co.uk

BladeRunnerJS - Divide & Conquer your Web Apps
BladeRunnerJS: Divide & Conquer your Web Apps

BladeRunnerJS is a development toolkit and lightweight framework for building web applications consisting of one or more components called Blades. It comes complete with some seriously useful tools which make it easy to develop, test and deploy your app.

Find out more