jQuery error when aborting an ajax call only in Internet Explorer
When mousing over an image in a jcarousel, my site displays a popup whose contents are loaded via ajax. I'm doing what I thought was fairly straightforward; keeping a handle to the xhrRequest object, and aborting the existing one before making a new request.
It work开发者_JAVA百科s great in all browsers except IE, where I receive an error "Object doesn't support this property or method"
Here's the code that is triggering it:
function showPopup {
// ... code snipped ...
// cancel the existing xhr request
if (showPopup.xhrRequest != null) {
showPopup.xhrRequest.abort();
showPopup.xhrRequest = null;
}
showPopup.xhrRequest = $.ajax({url: url,
type: "GET",
success:function(data) {
$("#popup-content").html(data);
}
});
// ... code snipped ...
}
showPopup.xhrRequest = null;
Works great in Firefox and Chrome. I traced the error down to this bit of code in jquery.js inside the ajax function (line 5233 in my copy of jQuery):
// Override the abort handler, if we can (IE doesn't allow it, but that's OK)
// Opera doesn't fire onreadystatechange at all on abort
try {
var oldAbort = xhr.abort;
xhr.abort = function() {
if (xhr ) {
oldAbort.call( xhr );
}
onreadystatechange( "abort" );
} catch(e) { }
The specific error occurs on the oldAbort.call( xhr ) line. Any ideas?
Found the answer to this on the jquery forums. See discussion here: http://forum.jquery.com/topic/object-doesn-t-support-this-property-or-method-from-jquery-1-4-1-in-ie7-only
The workaround for IE7 and below:
$.ajax({
...
xhr: function() {
if ($.browser.msie && $.browser.version.substr(0,1) <= 7)
return new ActiveXObject("Microsoft.XMLHTTP");
else
return new XMLHttpRequest();
},
...
});
The problem is that the XMLHttpRequest object provided by jQuery for Internet Explorer defaults to the COM implementation, not the native window.XMLHttpRequest
object, and its methods cannot be overridden.
Also, in the same scenario the abort
method is not a Javascript function, so it will not have a prototype and the call
method. abort
is not available at all on the ActiveX implementations as it was introduced with the native XMLHttpRequest object in IE7.
The native XMLHttpRequest was introduced in IE7, so what you're trying to do would never work in IE6 and it wouldn't work for some users in IE7/IE8 if they have native XMLHttpRequest
disabled in their settings (and I've come across this issue before).
You can change the default in jQuery using the xhr
option of $.ajax()
or $.ajaxSetup()
:
xhr
Callback for creating the XMLHttpRequest object. Defaults to the ActiveXObject when available (IE), the XMLHttpRequest otherwise. Override to provide your own implementation for XMLHttpRequest or enhancements to the factory.
(emphasis mine)
I got this issue in IE7 and made the following workaround in my app.
When making an ajax-request store the jqXHR somewhere and then when the callback get called act only if the jqHXR-parameter matches the on You stored.
doit = function(){
$("#target").data("req",$.getJSON(an_url,
{},
function(msg,status,xhr){
if(xhr===$("#target").data("req")){
$("<li/>").text(msg).appendTo("#target");
doit(luku);
} else {
$("<li/>").text("aborted!").appendTo("#target");
}
}));
}
An somewhere else You can call eg.
$("#target").data("req",false);
to "cancel" a pending request.
精彩评论