CORS with jQuery and XDomainRequest in IE8/9

62,605

Solution 1

POST method is supported, and to make a cross-domain https:// request your calling page would also need to be loaded over https. This is the best article I have found which explains these and other limitations of XDomainRequest in detail:

http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx

Solution 2

I've written a proxy which will gracefully downgrade to proxying if IE9 or less is used. You do not have to change your code at all if you are using ASP.NET.

The solution is in two parts. The first one is a jquery script which hooks into the jQuery ajax processing. It will automatically call the webserver if an crossDomain request is made and the browser is IE:

$.ajaxPrefilter(function (options, originalOptions, jqXhr) {
    if (!window.CorsProxyUrl) {
        window.CorsProxyUrl = '/corsproxy/';
    }
    // only proxy those requests
    // that are marked as crossDomain requests.
    if (!options.crossDomain) {
        return;
    }

    if (getIeVersion() && getIeVersion() < 10) {
        var url = options.url;
        options.beforeSend = function (request) {
            request.setRequestHeader("X-CorsProxy-Url", url);
        };
        options.url = window.CorsProxyUrl;
        options.crossDomain = false;
    }
});

In your web server you have to receive the request, get the value from the X-CorsProxy-Url http header and do a HTTP request and finally return the result.

My blog post: http://blog.gauffin.org/2014/04/how-to-use-cors-requests-in-internet-explorer-9-and-below/

Share:
62,605
Jeroen Ooms
Author by

Jeroen Ooms

#rstats developer and staff RSE for @ropensci at UC Berkeley.

Updated on December 29, 2020

Comments

  • Jeroen Ooms
    Jeroen Ooms over 3 years

    UPDATE: I highly recommend not investing any time in XDomainRequest, because it is a terribly poor implementation with many limitations. It basically only really works for GET requests to non-ssl servers, so you might as well use jsonp or whatever.


    I am using CORS to call a cross domain API, however Internet Explorer is giving issues. CORS should be possible in IE8 and IE9 through the XDomainRequest object, however I can't get things to work..

    JQuery refuses to provide native support for XDomainRequest, however several jQuery plugins are suggested to add this support. This topic suggest two such plugins: jQuery.XDomainRequest.js and xdr.js, which has been reported to work. Afaik, the plugins should automatically override behavior of jQuery.ajax. I found another plugin here.

    I put a little demo pages with the respective plugins jQuery.XDomainRequest and xdr and jquery.ie.cors that perform ajax requests to a CORS enabled server. The pages are working in Chrome and Firefox, however IE8/9 instantly throw a permission denied error (even before making the request). This MSDN post suggest adding another handler xhr.onprogress = function() {}; but I tried this and it isn't working either.

    Any clues what I am doing wrong? I have also tested with IE8 now using MS virtual server, but it has exactly the same problem.

    Edit: OK so I figured out that part of the problem was that I was using POST over HTTPS. Apparently XDomainRequest does not allow CORS over HTTPS. I can switch to HTTP but I really need POST.

    Edit2: See this issue on github for the end of this story. It turns out that when using HTTP POST, the xDomainRequest can only encode the request body (arguments) as text/plain. This pretty much makes it worthless, because everyone uses application/x-www-form-urlencoded or multipart/form-data.

  • monsur
    monsur over 11 years
    That is a good article that has several gotchas. I've referred to it many times in the past. Another one that comes up often: "Only text/plain is supported for the request's Content-Type header"
  • iGanja
    iGanja over 10 years
    The text/plain restriction makes this object completely worthless. A complete waste of programming effort on Microsoft's part IMHO.
  • Adam Alexander
    Adam Alexander over 10 years
    For common use cases such as JSON APIs at least, it's not quite as bad as it sounds. A web app can use XDomainRequest to send JSON data as text/plain. The server-side logic just needs to know to accept JSON sent with that Content-Type. Since CORS support already requires some changes on the server side this isn't much extra effort.
  • Jeroen Ooms
    Jeroen Ooms over 8 years
    This is just a jQuery wrapper around the same XDomainRequest method. It does not address any of the limitations described above.