Skip to main content

Bug Tracker

Side navigation

#8419 closed bug (wontfix)

Opened March 02, 2011 07:32AM UTC

Closed March 10, 2011 01:02AM UTC

Last modified March 09, 2012 08:20AM UTC

Ajax calls to encoded Internationalized domain names doesn't work in Internet Explorer

Reported by: Andreas Owned by: jaubourg
Priority: low Milestone: 1.next
Component: ajax Version: 1.5.1
Keywords: Cc:
Blocked by: Blocking:
Description

Using jQuery 1.5 or 1.5.1, any ajax() calls to encoded Internationalized domain names (IDN) (like xn--bcher-kva.ch) seems to fail in Internet Explorer 8. It worked fine in jQuery 1.4.4 and also with 1.5+ in any other browser than IE. It also works when using the unencoded domain name.

What happens in IE8 is that the ajax error callback is triggered with the not so helpful "error" in the textstatus variable, and jqXHR.responseText as "undefined".

I know I'm supposed to provide a test case, but unfortunately I only have access to one IDN, which belongs to a customer, so I can't. I hope this report can come to some use anyway. Maybe someone else who sees the ticket have access to a public IDN and can provide a test case (any simple ajax call will do).

Attachments (0)
Change History (9)

Changed March 03, 2011 12:41AM UTC by jaubourg comment:1

component: unfiledajax
owner: → jaubourg
priority: undecidedlow
status: newassigned

The error callback has a third parameter, errorThrown, what does it say?

Also, I don't quite understand what you're saying about which version has the bug. Do you mean 1.4.4 and 1.5+ fail on IE8 and work on any other browser or is it that 1.4.4 works in IE8 while 1.5+ doesn't?

Finally, if 1.4.4 also exhibits the bug, then it's a bug in IE8's xhr implementation that may not be workaroundable by jQuery.

Changed March 03, 2011 11:01AM UTC by Andreas comment:2

Replying to [comment:1 jaubourg]:

The error callback has a third parameter, errorThrown, what does it say? Also, I don't quite understand what you're saying about which version has the bug. Do you mean 1.4.4 and 1.5+ fail on IE8 and work on any other browser or is it that 1.4.4 works in IE8 while 1.5+ doesn't? Finally, if 1.4.4 also exhibits the bug, then it's a bug in IE8's xhr implementation that may not be workaroundable by jQuery.

The third parameter says "No Transport".

The error occurs in Internet Explorer 7 and 8 with jQuery 1.5+.

To summarize:

  • jQuery 1.4.4 & IE: Works fine.
  • jQuery 1.5 & IE: Fails.
  • jQuery 1.5.1 & IE: Fails.
  • error() parameters: jqXHR.responseText = "undefined", textStatus = "error", errorThrown = "No Transport".

Changed March 03, 2011 01:45PM UTC by jaubourg comment:3

OK, so the request is considered cross-domain and, since IE8 and below don't support cross-domain requests, ajax won't find a suitable transport and bail out.

What happens if you use the non-encoded url? Does IE support this? I've looked into the encoding code (in order for ajax to automagically encode domain names and fix the issue) but the encoding is complex and requires a LOT of code so I'm wondering if the encoding is necessary in the first place (one can hope IE makes it under the hood).

Changed March 03, 2011 04:45PM UTC by Andreas comment:4

Replying to [comment:3 jaubourg]:

OK, so the request is considered cross-domain and, since IE8 and below don't support cross-domain requests, ajax won't find a suitable transport and bail out. What happens if you use the non-encoded url? Does IE support this? I've looked into the encoding code (in order for ajax to automagically encode domain names and fix the issue) but the encoding is complex and requires a LOT of code so I'm wondering if the encoding is necessary in the first place (one can hope IE makes it under the hood).

The non-encoded url works, it's just the encoded one that does not work in jQuery 1.5+. Both, however, worked in jQuery 1.4.4. I hope there's a simple fix that can make it work again.

The cross domain thing you mention makes sense. IE probably does or lacks some conversion between the two domains. Maybe 1.4.4 had some clever work-around that was lost in the ajax rewrite of 1.5?

Changed March 04, 2011 04:32AM UTC by jaubourg comment:5

_comment0: No, actually, 1.5 added cross-domain detection. 1.4.4 just didn't bother controlling this and just let the browser's implementation throw an exception when it couldn't handle the request. With the new transport architecture, it makes sense to control this, seeing as it makes it possible to provide fail-over transports in browsers that doesn't support cross-domain. \ \ Anyway: \ 1) Do you absolutely need to use the encoded url? \ 2) Can't you use urls with no domain name (/something_on_the_server)? \ \ I don't really get why you're using the encoded domain name in your urls. It seems pretty easy (and much simpler for you incidently) to use the domain name unencoded. Or am I missing something gigantic here?1299213205979229

No, actually, 1.5 added cross-domain detection. 1.4.4 just didn't bother controlling this and just let the browser's implementation throw an exception when it couldn't handle the request. With the new transport architecture, it makes sense to control this, seeing as it makes it possible to provide fail-over transports in browsers that doesn't support cross-domain.

Anyway:

1) Do you absolutely need to use the encoded url?

2) Can't you use urls with no domain name (/something_on_the_server)?

I don't really get why you're using the encoded domain name in your urls. It seems pretty easy (and much simpler for you incidently) to use the domain name unencoded. Or am I missing something gigantic here?

Changed March 04, 2011 08:04AM UTC by Andreas comment:6

Replying to [comment:5 jaubourg]:

No, actually, 1.5 added cross-domain detection. 1.4.4 just didn't bother controlling this and just let the browser's implementation throw an exception when it couldn't handle the request. With the new transport architecture, it makes sense to control this, seeing as it makes it possible to provide fail-over transports in browsers that doesn't support cross-domain. Anyway: 1) Do you absolutely need to use the encoded url? 2) Can't you use urls with no domain name (/something_on_the_server)? I don't really get why you're using the encoded domain name in your urls. It seems pretty easy (and much simpler for you incidently) to use the domain name unencoded. Or am I missing something gigantic here?

Ah. I see.

I didn't write this bug report for my own selfish needs :), but to bring an undocumentet "broken" (in a way) behavior up to the community. Cross browser behavior is one of the jQuery features I appreciate the most.

There is, as you say, several workarounds for it. But for people upgrading existing systems from 1.4.4 to 1.5+ it can be real annoying to debug and not finding any information about this error (at least I didn't).

I'm not the original creator of the system I found this behavior in, but I think the reason for using the encoded domain is that the absolute URL is set server side with PHP. Server-side, the host name is always returned encoded. I don't think it's that uncommon to use an absolute URL for ajax calls, and with that, an encoded IDN. In more complex systems it might even be necessary. I find it kind of strange that no one else have reported this behavior (as far as I know).

Changed March 04, 2011 05:58PM UTC by jaubourg comment:7

I hear you. I made this prefilter: http://jsfiddle.net/jaubourg/2s5hZ/

It basically strips the domain given as the stripDomain option from given URLs. So you can drop the prefilter definition in your app and set the stripDomain option to your encoded domain name using ajaxSetup and you're good to go. It'll just do nothing in 1.4.4 and previous.

// In a separate file you include in your app as a plugin
// For instance jquery.strip-domain.js
(function() {
    if ( jQuery.ajaxPrefilter ) {
        
        var rURL = /^([^\\/]+)/,
            rEsc = /(\\-|\\.)/,
            protocol = rURL.exec( document.location.href )[ 1 ].replace( rEsc, "\\\\$1" ),
            rDomains = {};
        
        jQuery.ajaxPrefilter(function( options ) {
            var strip = options.stripDomain,
                rDomain,
                sDomain;
            if( strip ) {
                rDomain = rDomains[ strip ];
                if ( !rDomain ) {
                    sDomain = "^(?:" + protocol + ")?\\\\/\\\\/" + strip.replace( rEsc, "\\\\$1" );
                    rDomains[ strip ] = rDomain = new RegExp( sDomain, "i" )
                }
                options.url = options.url.replace( rDomain, "" );
            }
        });
    }

})( jQuery );

// In your app, after you loaded jQuery and the plugin
jQuery.ajaxSetup({
    stripDomain: "xn--bcher-kva.ch"
});

Changed March 07, 2011 01:04PM UTC by Andreas comment:8

Replying to [comment:7 jaubourg]:

I hear you. I made this prefilter: http://jsfiddle.net/jaubourg/2s5hZ/ It basically strips the domain given as the stripDomain option from given URLs. So you can drop the prefilter definition in your app and set the stripDomain option to your encoded domain name using ajaxSetup and you're good to go. It'll just do nothing in 1.4.4 and previous.

Thanks! And thank you for your time investigating this behavior.

Changed March 10, 2011 01:02AM UTC by jaubourg comment:9

resolution: → wontfix
status: assignedclosed