Обработка ошибок jQuery.ajax для междоменных вызовов jsonp
Я построил тестовый пример вызова ajax (jQuery 1.6.2), который выглядит так:
jQuery( document ).ready( function( $ ) {
var test = function( x ) {
$.ajax({
url: 'http://www.someotherdomain.com/test.php',
data: { x: x },
dataType: 'jsonp',
crossDomain: true,
success: function( data ) {
console.log( data.name );
},
error: function() {
x++;
test( x );
}
});
};
test( 1 );
});
И соответствующий файл test.php выглядит так:
if ( 5 > $_GET[ 'x' ] ) {
header('HTTP/1.1 503 Service Temporarily Unavailable'); die();
} else {
header( 'content-type: application/x-javascript' );
echo $_GET[ 'callback' ] . '({"name":"Morgan"})';
}
Несмотря на то, что документация jQuery указывает, что обработчик ошибок для вызовов jsonp никогда не запускается, этот script работает так, как я предполагал. Это приводит к четырем "неудачным" вызовам test.php, которые возвращают 503 ошибки, а затем test()
рекурсивно называет себя приращением x до тех пор, пока ajax-вызов не будет "успешным", и данные будут выводиться на консоль.
Итак, мой тестовый пример выше, но мой фактический код не работает, что больше похоже на следующее:
jQuery( document ).ready( function( $ ) {
var completed = 0;
var fiftystates; // assume an array of state objects
var updateState = function( index, state ) {
var d = index % 5; // for subdomains sub0, sub1, sub2, sub3, sub4
$.ajax({
url: 'http://sub' + d + '.mydomain.com/update_state.php',
data: { state: state.id },
dataType: 'jsonp',
crossDomain: true,
success: function() {
completed++;
var complete_percent = completed / fiftystates.length * 100;
$( '#progressbar' ).progressbar( 'value', completed_percent );
},
error: function() {
updateState( index, state );
}
}); // end ajax
}; // end updateState
$( fiftystates ).each( updateState );
};
Как вы можете видеть, это проходит через 5 разных поддоменов, которые на самом деле являются зеркалами того же домена, но так как update_state.php может занять до 30 секунд, это займет 25-минутный процесс до менее чем три минуты. Проблема заключается в том, что серверный стук приводит к сбою некоторых запросов ajax с ошибкой 503. В моем тестовом случае это было обработано без проблем, но в моем втором примере обработчик ошибок никогда не появляется.
Я не могу понять, почему тестовый сценарий работает так, как я ожидаю, а второй - нет. Любые идеи?
Ответы
Ответ 1
должен ли он быть в таком формате:
$.ajax({
type: "POST",
url: 'http://servername/WebService.svc/GetData?callback=?',
dataType: 'jsonp',
success: function (data) {
//do stuff
},
error: function (msg, b, c) {
//alert error
}
});
Ответ 2
В вашем тестовом примере вы меняете значение x для каждого вызова...
В другом коде вы отправляете одно и то же значение индекса. Который вернет тот же результат, а не "вращается" через поддомены...
error: function() {
index++;
updateState( index, state );
}
Ответ 3
Если случайно вы использовали IE для проверки первого случая и, возможно, FF или Chrome для проверки второго случая, это может быть причиной. Ошибки и глобальные обратные вызовы не вызываются для типов JSON/JSONP междоменного домена, как это описано в функции jQuery.ajax. Тем не менее, я заметил, что они все еще вызываются в IE, и я думаю, что это имеет какое-то отношение к jQuery, используя IE XMLHttpRequest для выполнения вызовов.
Похоже, кто-то любезно создал плагин, который обрабатывает ошибки с запросами JSONP, доступными здесь: http://code.google.com/p/jquery-jsonp/
Ответ 4
function AjaxRequest(url, params){
return $.ajax({
url: url,
data: params,
dataType: 'jsonp',
/* Very important */
contentType: 'application/json',
});
}
var test = function(x) {
AjaxFeed('http://servername/WebService.svc/GetData', {x: x})
/* Everything worked okay. Hooray */
.done(function(data){
console.log(data);
})
/* Oops */
.fail(function(jqXHR, sStatus, oError) {
console.log(arguments);
});
}
jQuery(window).load(function() {
test('test');
}