обработка ошибок 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 никогда не запускается, этот сценарий работает. как я и предполагал. Он делает четыре «неудачных» вызова 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. В моем тестовом случае это было обработано без проблем, но во втором примере обработчик ошибок никогда не вызывается.

Я не могу понять, почему тестовый пример работает так, как я ожидаю, а второй - нет. Любые идеи?


person morphatic    schedule 07.10.2011    source источник
comment
попытался перейти на jQuery 1.6.4 с тем же результатом   -  person morphatic    schedule 07.10.2011
comment
может быть, использование php header() для возврата 503 ведет себя иначе, чем фактическое 503? Я изучил заголовки HTTP в обоих случаях, и они выглядят одинаково для меня...   -  person morphatic    schedule 07.10.2011
comment
В первом примере вы увеличиваете x каждый раз (x++;) в обработчике ошибок. Во втором вы не увеличиваете index++; это единственная очевидная разница, которую я вижу.   -  person Kato    schedule 24.10.2011
comment
Кроме того, пробовали ли вы тест 503 без команды die()? Может ли это предотвратить добавление дополнительных заголовков сервера, которые заставляют его использовать успех во втором случае?   -  person Kato    schedule 24.10.2011
comment
Кроме того, разве ваш вызов заголовка не должен быть таким? заголовок (HTTP/1.0 503 Служба временно недоступна, правда, 503); может быть, поэтому они ведут себя по-другому? Дополнительные мысли см. здесь: stackoverflow.com/questions/2760884/ (хорошо, я иду :))   -  person Kato    schedule 24.10.2011


Ответы (3)


должно быть в таком формате:

$.ajax({
    type: "POST",
    url: 'http://servername/WebService.svc/GetData?callback=?',
    dataType: 'jsonp',
    success: function (data) {
       //do stuff
    },
    error: function (msg, b, c) {
    //alert error
    }
 });
person Shawn    schedule 02.01.2013
comment
JSONP нельзя использовать для выполнения запросов POST между доменами. jQuery автоматически изменит это на запрос GET. - person cesarislaw; 12.02.2014
comment
проверьте веб-сайт jquery. Примечание. Этот обработчик не вызывается для междоменных сценариев и междоменных запросов JSONP. - person shereifhawary; 20.04.2014

В вашем тестовом примере вы меняете значение x для каждого вызова...

В другом коде вы отправляете одно и то же значение индекса. Который вернет тот же результат, вместо того, чтобы «вращаться» по субдоменам...

    error: function() {
        index++;
        updateState( index, state );
    }
person blindfold    schedule 22.12.2011
comment
Параметр index автоматически увеличивается при вызове функции jQuery.each() в предпоследней строке. Хорошая мысль, но я не думаю, что это проблема. - person morphatic; 24.12.2011
comment
Я понимаю, что индекс изменяется вызовом функции .each(). Тем не менее, это не влияет на индекс, который вызывается в случае ошибки. Для каждого состояния в вашем массиве вы вызываете функцию, которая вызывает себя в случае ошибки... - person blindfold; 02.01.2012

Если случайно вы использовали IE для тестирования первого случая и, возможно, FF или Chrome для тестирования второго случая, то это может быть причиной. Обратные вызовы Error и Global не вызываются для междоменных типов JSON/JSONP, как описано в функции jQuery.ajax. Однако я заметил, что они все еще вызываются в IE, и я думаю, что это как-то связано с jQuery, использующим IE XMLHttpRequest для выполнения вызовов.

Похоже, кто-то любезно создал подключаемый модуль, который обрабатывает ошибки с запросами JSONP, доступный здесь: http://code.google.com/p/jquery-jsonp/

person WhoopP    schedule 09.01.2012