问题
Please check: http://jsfiddle.net/TWiStErRob/s2jSA/ where I try set up all possible variations I could think of for:
success, error, complete
ajaxSetup
ajaxSuccess, ajaxError, ajaxComplete
done, fail, always
As I see:
- a lot of events are missing for JSONP
I would expect the same output as for JSON - Global AJAX events don't work as the Deferred's callbacks, i.e. registration order matters, but only with the same type of events.
Not a biggie, I can live with it. - complete is running after success/error
Good to know.
It seems that for JSONP the events are almost useless, can someone please explain why and give a workaround?
回答1:
Reason
From http://api.jquery.com/category/ajax/global-ajax-event-handlers/
Note: Global events are never fired for cross-domain script or JSONP requests, regardless of the value of global.
From http://bugs.jquery.com/ticket/8338
JSONP requests are not guaranteed to complete (because errors are not caught). jQuery 1.5 forces the global option to false in that case so that the internal ajax request counter is guaranteed to get back to zero at one point or another.
If you want all requests to fire the events, no matter what (and at the risk of the same inconsistencies 1.4.4 exhibited), you can use the following prefilter:
jQuery.ajaxPrefilter(function( options ) {
options.global = true;
});
Workaround
The above code indeed makes it work:
$.ajaxPrefilter(function global_ajaxPrefilter(options, originalOptions, jqXHR) {
options.global = true;
});
$(document).ajaxSuccess(function global_ajaxSuccess(event, XMLHttpRequest, ajaxOptions) {
if(config.logResponses) {
console.log(XMLHttpRequest.responseText);
}
});
$(document).ajaxError(function global_ajaxError(event, jqXHR, ajaxSettings, thrownError) {
console.error("error: " + jqXHR.status + " " + thrownError);
});
However for my purposes the following approach works better:
$.ajaxPrefilter(/*dataTypes, */ function global_ajaxPrefilter(options, originalOptions, jqXHR) {
if(config.logResponses) {
jqXHR.done(function global_ajaxSuccess(data, textStatus, jqXHR) {
console.groupCollapsed(options.url + (options.data ? '&' + $.param(options.data) : ''));
console.log("Options: " + JSON.stringify(options));
console.log("Data: " + JSON.stringify(data));
console.groupEnd();
});
}
jqXHR.fail(function global_ajaxError(jqXHR, textStatus, errorThrown) {
console.error(textStatus + ": " + errorThrown));
});
});
Notice the different argument list of global_ajaxSuccess and global_ajaxError:
options: available in both solutions (contains URL)data: is available as text in global handler, and object indone- interface is much familiar with
done/error
来源:https://stackoverflow.com/questions/18730526/jquery-global-and-local-ajax-events-are-not-firing