Skip to main content

Bug Tracker

Side navigation

#8283 closed enhancement (plugin)

Opened February 15, 2011 03:42PM UTC

Closed December 10, 2011 06:51PM UTC

Last modified March 12, 2013 04:14PM UTC

Built-in support for XDomainRequest

Reported by: plus.ajg+jquery@gmail.com Owned by:
Priority: low Milestone: 1.next
Component: ajax Version: 1.5
Keywords: 1.8-discuss Cc:
Blocked by: Blocking:
Description

Internet Explorer version 8 and up, in traditional Microsoft fashion, includes an alternative version of the XMLHttpRequest object named XDomainRequest; they share very similar interfaces, but the latter supports certain forms of cross-domain requests.

More information about it can be located here:

http://msdn.microsoft.com/en-us/library/cc288060(v=vs.85).aspx

It would be great if jQuery automatically used said object, where available, in ajax calls, when it detects an attempt to make a (non-JSONP) cross-domain request using Internet Explorer.

''(Apologies in advance if this is not the right place for this issue or if it has already been dealt with; I've perused other tickets as well as the ajax support code to no avail. In particular, jQuery.support.cors does not seem to trigger the use of XDomainRequest.)''

Thanks,

Alvaro

Attachments (0)
Change History (36)

Changed February 15, 2011 04:08PM UTC by jitter comment:1

component: unfiledajax
priority: undecidedlow
resolution: → duplicate
status: newclosed

Thanks for taking the time to contribute to the jQuery project by writing an enhancement request.

There are currently no plans to support this in core and is better suited as a plugin.

But with the ajax rewrite that landed for 1.5 you should be able to write your own transport to handle non-JSONP cross-domain requests with IE.

Please checkout http://api.jquery.com/extending-ajax/ for more info.

If you happen to write a custom transport as jQuery plugin that uses XDomainRequest you might want to report back and add a link to it here so that others how happen to find this ticket can easily find it.

Changed February 15, 2011 04:08PM UTC by jitter comment:2

Duplicate of #3342.

Changed April 25, 2011 07:38PM UTC by anonymous comment:3

As an observation, this doesn't seem to be a duplicate of the #3342 to me. This would seem to be fodder for core work IMHO as it centers on mitigating browser-specific idiosyncrasies, but I'll respect this decision as better informed.

For reference and for the benefit of others trying to deal with IE's apparent non-support for Cross-Origin Resource Sharing via XMLHttpRequest (and their alternative: XDomainRequest) I'll offer this reference to a work-around which I found (not tested by me, yet).

http://graphicmaniacs.com/note/getting-a-cross-domain-json-with-jquery-in-internet-explorer-8-and-later/

Changed May 06, 2011 08:00AM UTC by T.J. Crowder comment:4

_comment0: Have to agree with @jitter and @anonymous: jQuery works around a wide variety of browser inconsistencies, that's probably about half its purpose (the other half being simplifying complex operations). This is a classic browser inconsistency: Chrome and Firefox support [http://www.w3.org/TR/access-control/ CORS] via `XMLHttpRequest`; IE instead uses `XDomainRequest`. It makes no more sense for this to be a plug-in than it would for (say) handling IE's broken `getAttribute` function being a plug-in. Recommend reopening and scheduling for 1.6.1 or 1.6.2 (especially as jQuery now has the `jqXHR` concept).1304669138636605

Have to agree with @anonymous: jQuery works around a wide variety of browser inconsistencies, that's probably about half its purpose (the other half being simplifying complex operations). This is a classic browser inconsistency: Chrome and Firefox support CORS via XMLHttpRequest; IE instead uses XDomainRequest. It makes no more sense for this to be a plug-in than it would for (say) handling IE's broken getAttribute function being a plug-in. Recommend reopening and scheduling for 1.6.1 or 1.6.2 (especially as jQuery now has the jqXHR concept).

Changed May 09, 2011 09:24PM UTC by S. Legay comment:5

+1. IE still represents a very large number of users. It doesn't make any sense for jQuery core to start being picky about what browsers it wants to support.

True cross-domain Ajax seems to be possible in all major browsers, and should be fully supported by jQuery. There are many scenarios where jsonp just isn't good enough.

Changed May 09, 2011 09:28PM UTC by rwaldron comment:6

Run this in IE6, when the result is "true" then it will be viable. I hate it as much as anyone, I promise.

http://jsfiddle.net/rwaldron/Lrx6q/

Changed May 10, 2011 01:14PM UTC by rwaldron comment:7

resolution: duplicate
status: closedreopened

So, the real beauty of jaubourg's ajax rewrite is that adding a custom transport type is super easy. All you need to do is add a new file with your custom transport logic to the src/ajax directory and then add a line to the BASE_FILES in Makefile

Good luck and let us know if you need any help along the way!

Changed May 10, 2011 01:15PM UTC by rwaldron comment:8

resolution: → patchwelcome
status: reopenedclosed

Changed May 13, 2011 08:20AM UTC by samuel@oriontransfer.org comment:9

I was doing some review of the feasibility of using XDomainRequest, and while I haven't actually written any code, it seems like a lot of people have found that it is generally pretty broken in comparison to XMLHttpRequest - I'm still going to try and write some code but I'm not completely sure it is useful. I thought I'd post this note here for other people who are interested in cross domain XMLHttpRequest.

Changed May 18, 2011 06:21AM UTC by braunsquared@gmail.com comment:10

Here is an example of the XDomainRequest transport we are using. Due to the poor error handling of XDomainRequest, we have support built into our backend which will return all errors as an xml document in the form of

<error response_code="xxx" message_key="abc">English Message</error>

Also, XDomainRequest only support text responses so that needs to be taken into account as well as is included below.

Please keep in mind that XDomainRequest adds the data as the text body of the request and this needs to be taken into account on the server side. We do detection of IE as the agent and take actions according in our request processing.

Please feel free to use the following code snippet to help you in any way, shape or form.

$.ajaxTransport( function( options, originalOptions, jqXHR ) {
    var xdr;

    return {
        send: function( _, completeCallback ) {
            xdr = new XDomainRequest();
            xdr.onload = function() {
                var responses = {
                    text: xdr.responseText
                };

                if (xdr.contentType.match(/\\/xml/)){
                    // there is no responseXML in XDomainRequest, so we have to create it manually
                    var dom = new ActiveXObject('Microsoft.XMLDOM');
                    dom.async = false;
                    dom.loadXML(xdr.responseText);
                    responses.xml = dom;

                    if($(dom).children('error').length != 0) {
                        var $error = $(dom).find('error');
                        completeCallback(parseInt($error.attr('response_code')), $error.attr('message_key'), responses);
                    } else {
                        completeCallback(200, 'success', responses);
                    }

                } else {
                    completeCallback(200, 'success', responses); // we will assume that the status code is 200, XDomainRequest rejects all other successful status codes
                // see bug https://connect.microsoft.com/IE/feedback/ViewFeedback.aspx?FeedbackID=334804
                }
            };
            xdr.onerror = xdr.ontimeout = function() {
                var responses = {
                    text: xdr.responseText
                };
                completeCallback(400, 'failed', responses);
            }

            xdr.open(options.type, options.url);
            if('POST' == options.type) {
                xdr.send(options.data);
            }
        },
        abort: function() {
            if(xdr) {
                xdr.abort();
            }
        }
    };
});

Changed May 18, 2011 06:29AM UTC by braunsquared@gmail.com comment:11

My apologies. There's a typo in the above snippet. It should read:

xdr.open(options.type, options.url);
xdr.send(options.data);

The "if" isn't needed.

Changed October 12, 2011 09:00PM UTC by ryanttb comment:12

If you only expect a text or json response, this version of the above works in IE9, even if you don't specify dataType: "json" in the ajax request:

$.ajaxTransport( function( options, originalOptions, jqXHR ) {
  var xdr;

  return {
    send: function( _, completeCallback ) {
      xdr = new XDomainRequest();
      xdr.onload = function() {
        if (xdr.contentType.match(/\\/json/)) {
          options.dataTypes.push("json");
        }

        completeCallback(200, 'success', { text: xdr.responseText } );
      };
      xdr.onerror = xdr.ontimeout = function() {
        completeCallback(400, 'failed', { text: xdr.responseText } );
      }

      xdr.open(options.type, options.url);
      xdr.send(options.data);
    },
    abort: function() {
      if(xdr) {
        xdr.abort();
      }
    }
  };
});

Changed November 04, 2011 12:06AM UTC by mattmanic comment:13

This is unbelievable that this is a known incompatibility for $.ajax for cross domain requests, and the core team are doing nothing about it. If it's as simple as adding a transport (which I'm trying do without luck), then why are the core team not including this for IE8+?

Guys, please address this is part of JQuery. Isn't that the point of JQuery, that it shields you from browser peculiarities?

Changed November 04, 2011 12:52AM UTC by jaubourg comment:14

_comment0: Replying to [comment:16 mattmanic]: \ > This is unbelievable that this is a known incompatibility for $.ajax for cross domain requests, and the core team are doing nothing about it. If it's as simple as adding a transport (which I'm trying do without luck), then why are the core team not including this for IE8+? \ > \ > Guys, please address this is part of JQuery. Isn't that the point of JQuery, that it shields you from browser peculiarities? \ \ Have you tried [https://github.com/jaubourg/ajaxHooks/blob/master/src/ajax/xdr.js this transport]?1320368019893661

Replying to [comment:16 mattmanic]:

This is unbelievable that this is a known incompatibility for $.ajax for cross domain requests, and the core team are doing nothing about it. If it's as simple as adding a transport (which I'm trying do without luck), then why are the core team not including this for IE8+? Guys, please address this is part of JQuery. Isn't that the point of JQuery, that it shields you from browser peculiarities?

Have you tried this transport?

(and as a side note, you realize that jQuery simply can't "shield you" in IE6 and IE7 for instance)

Changed November 30, 2011 01:39PM UTC by anonymous comment:15

Replying to [comment:17 jaubourg]:

Have you tried this transport?

This may be a dumb question, but is there a reason this isn't in jQuery core (yet)? Seems like you fulfilled the 'patchneeded' criterium, at least (potential review comments aside).

Changed December 08, 2011 11:13AM UTC by steve_pax comment:16

This functionality should definitely be part of the jQuery core - avoiding browser inconsistencies is one of the huge strengths of jQuery!

Changed December 10, 2011 06:51PM UTC by dmethvin comment:17

resolution: patchwelcome
status: closedreopened

Changed December 10, 2011 06:51PM UTC by dmethvin comment:18

resolution: → plugin
status: reopenedclosed

Changed December 10, 2011 06:53PM UTC by dmethvin comment:19

Reopening for discussion, but in the meantime I'll close this as plugin since there is a solution available here:

https://github.com/jaubourg/ajaxHooks/blob/master/src/ajax/xdr.js

Microsoft's XDR is not supported in IE6/7, and BTW the IE10 beta was just released with CORS support interfaces equivalent to other browsers.

Changed December 10, 2011 06:53PM UTC by dmethvin comment:20

keywords: → 1.8-discuss

Changed December 10, 2011 07:20PM UTC by dmethvin comment:21

-1, Given the lame-duck status of XDR and its limitations I don't think this is worth the bytes. http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx

Changed December 25, 2011 09:04AM UTC by jquery@lianza.org comment:22

Replying to [comment:23 dmethvin]:

Reopening for discussion, but in the meantime I'll close this as plugin since there is a solution available here: https://github.com/jaubourg/ajaxHooks/blob/master/src/ajax/xdr.js

This solution works for me in IE8, but in IE9 I see the request show up as "Aborted." Has anyone had luck with this workaround in IE9?

Changed January 20, 2012 08:57PM UTC by dmethvin comment:23

#11202 is a duplicate of this ticket.

Changed January 26, 2012 06:28PM UTC by anonymous comment:24

Changed March 04, 2012 01:26AM UTC by anonymous comment:25

JQuery refuses to do CORS in IE9 without this support. IE9 gave me a "access denied" to let me know that using 1.4.4 ....not the case using 1.7.1. Not sure if that's poor debug/communication between IE9 or not. Either way, this was confusing to me for about an hour...

Changed May 03, 2012 01:50PM UTC by troyharvey@gmail.com comment:26

xdr.js
plugin from @jabourg with the IE9 fix:

@tlianza's xdr.js

Changed June 01, 2012 03:17AM UTC by timMcKendrick comment:27

Concurring that it's absolutely insane for this not to be in the core. It's a massively useful patch that shouldn't have to be wedged in like this.

Thanks for the code!

Changed June 21, 2012 10:59AM UTC by Drizzt comment:28

@dmethvin: it'd still be helpful to have this in jQuery core, since not all users would (be able to) switch to IE10 the moment the final release is out. And having to use some plugin on _all_ projects, which rely on some AJAX functionality (with CORS) is simply not looking like a good solution. Maybe installing the transport conditionally would be an option?

So my vote is in favour of adding this to jQuery core.

Changed July 25, 2012 12:40AM UTC by cjo@sendfaster.com comment:29

+1 for adding this to core. The plugin route is a pain in the rear end and requires adding a dependency on a plugin for code which must be distributed. Rather than simply saying "requires jQuery > x" distributing code requires a complete set of instructions for adding the plugin (or else bundling it with the distributed code, which presents a host or problems of it's own).

Changed August 08, 2012 04:39PM UTC by anonymous comment:30

If JQuery still wants to be true to its values, this definitely sounds like something that should be in the core as soon as possible!

Changed August 08, 2012 04:41PM UTC by rwaldron comment:31

@anonymous If it can't be done in all browsers that jQuery supports, then jQuery doesn't do it.

Changed August 08, 2012 04:44PM UTC by dmethvin comment:32

To everyone asking for this to be in jQuery core: You understand that this will still not make IE8/9 cross-domain ajax support that works the same as the other browsers. Right? And you're willing to deal with all the special cases that contradict the documentation currently in $.ajax. Right? And it won't work in IE 6/7 which are still around. Right? And you're not going to file bugs against them, since we can't fix them. Right?

How many of you have actually used the XDomainRequest plugin mentioned above and understand its limitations?

Changed August 15, 2012 06:01AM UTC by Jock Murphy <jock@jockmurphy.com> comment:33

dmethvin, I would rather a jQuery that tries rather than one which does nothing. Yes there will be cases it can't handle... AND it might even be able to give an intelligible error messages in those cases. As opposed to, say, failing with no explanation and no clue to the user why it is failing. I lost hours to this today with no clue why it was an issue.

jQuery isn't a perfect shield against IE6, but it tries. Why can't this logic be applied to IE8 & 9 and XDR?

Changed August 15, 2012 01:03PM UTC by dmethvin comment:34

It was a jQuery team member who **tried** and wrote the plugin available above. What is the problem with people using that again? You can get assistance with using the plugin on the forum if you need it. If the plugin needs to emit better error messages, perhaps you could work on that since it seems to be very important to you.

Changed January 09, 2013 12:32AM UTC by dmethvin comment:35

PLEASE READ

Summary of the XDomainRequest issue:

  • IE 6, 7, 8, and 9 do not support XHR2 CORS. It is **not** possible to make generalized cross-domain requests in these browsers.
  • IE 8, 9 support an ActiveX control called XDomainRequest that only allows **limited** cross-domain requests compared to XHR2 CORS.
  • IE 10 supports XHR2 CORS.
  • jQuery does not include XDomainRequest support because there are numerous and serious limitations to XDR. Many reasonable $.ajax requests would fail, including **any** cross-domain request made on IE6 and IE7 which are otherwise supported by jQuery. Developrers would be confused that their content types and headers were ignored, or that IE8 users couldn't use XDR if the user was using InPrivate browsing for example.
  • Even the crippled XDR can be useful if it is used by a knowledgeable developer. A jQuery team member has made an XDR ajax transport available. You must be aware of XDR limitations by reading this blog post or ask someone who has dealt with XDR problems and can mentor you through its successful use.
  • For further help and other solutions, ask on the jQuery Forum, StackOverflow, or search "jQuery xdr transport". Requests posted here will be deleted.

Changed March 12, 2013 04:14PM UTC by brad@musatcha.com comment:36

For anyone getting a 404 on the xdr.js plugin mentioned above, it has been moved here:

https://github.com/jaubourg/ajaxHooks/blob/master/src/xdr.js