обработка ошибок jQuery.ajax для междоменных вызовов jsonp - PullRequest
14 голосов
/ 07 октября 2011

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

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

Ответы [ 4 ]

4 голосов
/ 02 января 2013

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

$.ajax({
    type: "POST",
    url: 'http://servername/WebService.svc/GetData?callback=?',
    dataType: 'jsonp',
    success: function (data) {
       //do stuff
    },
    error: function (msg, b, c) {
    //alert error
    }
 });
3 голосов
/ 10 января 2012

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

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

3 голосов
/ 22 декабря 2011

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

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

    error: function() {
        index++;
        updateState( index, state );
    }
1 голос
/ 19 октября 2013
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');
}
...