JQuery.ajax - always () doesn't always work
I am using jQuery.ajax to make a REST call and get some JSON. It works as expected. However, when I call an error condition like an invalid url, the method always fails. If I set crossDomain = false or dataType = 'json' then it always fires. But I cannot do this in my production code. If you set url = ' http://ip.jsontest.com/ ' it always works. I created a small example to illustrate the problem:
var jqXHR = jQuery.ajax({
type: 'GET',
async: false,
cache: false,
url: 'http://ip.jsontest.com.BADURL/',
contentType: 'application/json; charset=UTF-8',
crossDomain: true,
dataType: 'jsonp'
})
.done(function (data, textStatus, jqXHR) {
console.log('Your IP is ' + data.ip);
console.log('done was called');
})
.fail(function (jqXHR, textStatus, errorThrown) {
console.log('fail was called');
})
.always(function (dataOrjqXHR, textStatus, jqXHRorErrorThrown) { console.log('always was called'); });
You can run this in the console at jquery.com which uses jQuery 1.9.1. I have the same behavior using jQuery 1.11.1. I always need to shoot to handle times when the URL is not available. I get the same behavior in IE11, Chrome 38 and FF 33. Am I doing something wrong or is this a bug? Thank.
source to share
This is what is known for JSONP calls. According to $. Ajax link for error
:
Note. This handler is not called for cross-domain script and cross-domain JSONP requests.
Also note that synchronous JSONP calls are not supported:
Cross-domain and dataType requests: "jsonp" requests do not support synchronous operation.
Workarounds typically include 1) setting a timeout for the call, or 2) using a plugin to add more typical error
functionality.
1) Setting a timeout (and async true)
var jqXHR = jQuery.ajax({
type: 'GET',
async: true,
cache: false,
url: 'http://ip.jsontest.com.BADURL/',
contentType: 'application/json; charset=UTF-8',
crossDomain: true,
dataType: 'jsonp',
timeout: 2000
})
.fail(function (jqXHR, textStatus, errorThrown) {
console.log('fail was called');
})
.done(function (data, textStatus, jqXHR) {
console.log('Your IP is ' + data.ip);
console.log('done was called');
})
.always(function (dataOrjqXHR, textStatus, jqXHRorErrorThrown) { console.log('always was called'); });
2) jQuery JSONP plugin which adds error recovery functionality.
source to share