Подтвердить что ты не робот

JQuery ajax общая обработка ошибок и в каждом конкретном случае

У меня есть общий обработчик ошибок ajax, написанный так:

$('html').ajaxError(function(e, xhr, settings, exception) {

    var message = '';

    if (xhr.status == 0) {
        message = 'You are offline!\n Please check your network.';
    }
    else if (xhr.status == 403) {
        window.location.href = $('#logon').attr('href');
    }
    else if (xhr.status == 404) {
        message = 'Requested URL not found.';
    }
    else if (xhr.status == 500) {

        message = xhr.responseText;

        $('#cboxLoadedContent div.news_article_content').append('<p>' + message + '</p>');

        try {//Error handling for POST calls
            message = JSON.parse(xhr.responseText);
        }

        catch (ex) {//Error handling for GET calls
            message = xhr.responseText;
        }

    }
    else if (errStatus == 'parsererror') {
        message = 'Error.\nParsing JSON Request failed.';

    }
    else if (errStatus == 'timeout') {
        message = 'Request timed out.\nPlease try later';
    }
    else {
        message = ('Unknown Error.\n' + xhr.responseText);
    }

    if (message != '' && xhr.status != 500) {
        message = message;
    }

    if (xhr.status != 403) {

        $('#icis_dashboard').append('<p id="ajax_error_msg" class="offScreen">' + message + '</p>');

        errorBox({
            inline: true,
            width: 0,
            href: '#ajax_error_msg',
            onLoadCall: function() { $('#cboxLoadedContent').jScrollPaneRemove(); },
            onCleanupCall: function() { $('#ajax_error_msg').remove(); }
        });
    }

});

Поэтому, когда ошибка не 403, отображается диалог с текстом, относящимся к ошибке.

Это прекрасно, но то, что мне хотелось бы сделать, это иметь общий обработчик в качестве резервной копии, а затем обрабатывать каждую ошибку на индивидуальной основе в исходном вызове ajax.

так как обработчик резервной копии предупреждает "бар" на 404, я хотел бы предупредить "foo":

            error: function(xhr) {
            if (xhr.status == 404) {
                //window.location.href = $('#logon').attr('href');
                alert("foo");    
            }
        }

Я все равно сделаю это? Я не знаю, как предотвратить резервное копирование при стрельбе, поскольку оба они кажутся запущенными в данный момент.

4b9b3361

Ответ 1

Я не думаю, что вы можете контролировать это с помощью jQuery. Глобальная ajaxError вызывается при любой ошибке, которая происходит во время вызова ajax. Тем не менее, "локальный" обратный вызов ошибки вызывается перед глобальным обратным вызовом, поэтому вы можете установить переменную, которая сообщает глобальному обратному вызову не запускаться.

Например:

var handledLocally = false;

$('html').ajaxError(function(e, xhr, settings, exception) {
    if (!handledLocally){
        //run the normal error callback code and the reset handledLocally
    }
});

error: function(){
    //set handledLocally to true to let the global callback it has been taken care of
    handledLocally = true;
}

Вы можете просмотреть этот jsFiddle, который показывает, как это может быть выполнено (обязательно нажмите кнопку прокрутки вверху, прежде чем нажимать ссылки): http://jsfiddle.net/e7By8/

Ответ 2

Вы можете установить для свойства ajax "global" значение false в функции ajax, которая выполняет обработку ошибок. Это должно предотвратить глобальную обработку ошибок. Проверьте: http://api.jquery.com/jQuery.ajax#toptions.

Ответ 3

Я думаю, что глобальная переменная - это плохая идея, потому что вы можете одновременно иметь несколько запросов ajax. Как уже упоминалось, "локальная" ошибка обратного вызова вызывается перед глобальным обратным вызовом. Мое решение просто присоединяет какое-то настраиваемое свойство к объекту jqXHR, например handledLocally и устанавливает его true в вашем локальном обработчике и проверяет его в глобальном обработчике.

Локальная обработка:

$.ajax({
   //some settings
   error:function(jqXHR, textStatus, errorThrown){
      //handle and after set
      jqXHR.handledLocally = true

   }
})

глобальная обработка:

$(document).ajaxError(function (event, jqXHR, ajaxSettings, thrownError) {
    if (jqXHR.handledLocally)) {
        return;
    }
    //handle global error
})

Ответ 4

Фактически мы решили это следующим образом:

function ajaxError(xhr, textStatus, errorThrown) {

    var message = '';

    if (xhr.status == 0) {
        message = 'You are offline!\n Please check your network.';
    }
    else if (xhr.status == 403) {
        window.location.href = $('#logon').attr('href');
    }
    else if (xhr.status == 404) {
        message = 'Requested URL not found.';
    }
    else if (xhr.status == 500) {

        message = xhr.responseText;

        $('#cboxLoadedContent div.news_article_content').append('<p>' + message + '</p>');

        try {//Error handling for POST calls
            message = JSON.parse(xhr.responseText);
        }

        catch (ex) {//Error handling for GET calls
            message = xhr.responseText;
        }

    }
    else if (errStatus == 'parsererror') {
        message = 'Error.\nParsing JSON Request failed.';

    }
    else if (errStatus == 'timeout') {
        message = 'Request timed out.\nPlease try later';
    }
    else {
        message = ('Unknown Error.\n' + xhr.responseText);
    }

    if (message != '' && xhr.status != 500) {
        message = message;
    }

    if (xhr.status != 403) {

        $('#icis_dashboard').append('<p id="ajax_error_msg" class="offScreen">' + message + '</p>');

        errorBox({
            inline: true,
            width: 0,
            href: '#ajax_error_msg',
            onLoadCall: function() { $('#cboxLoadedContent').jScrollPaneRemove(); },
            onCleanupCall: function() { $('#ajax_error_msg').remove(); }
        });
    } 
};

Таким образом, каждый вызов AJAX будет ссылаться на funciton одним из двух способов:

1), если мы хотим, чтобы по умолчанию было выполнено

error: ajaxError

2), если мы хотим настроить таргетинг на конкретную ситуацию, если это не удалось поймать, перейдите к стандартным

    error: function(xhr) {

        if (xhr.status == 404) {
            alert("local");
        }
        else {
            // revert to default
            ajaxError.apply(this, arguments);
        }
    }

Ответ 5

Это старый вопрос, но это может быть полезно для кого-то. Проблема с этим ответом заключается в том, что у вас может быть код в глобальных обработчиках, который нужно выполнить. Я нашел этот другой ответ более полезным, но это не очень хорошая практика для использования глобальных переменных. Также вы можете иметь более одного вызова ajax одновременно, и это не будет работать. Я предлагаю эту альтернативу несколько иначе:

$(document).ajaxError(function(event, jqxhr, settings, thrownError) {
    // Global validation like this one:
    if (jqxhr.status == 401) { window.location = "/login"; }

    if (!settings.handErrorLocally) {
        // Unhandled error.
        alert("Ooops... we have no idea what just happened");
    }
});

И затем, когда вы вызываете какой-либо ajax, вы можете самостоятельно обработать ошибку:

$.ajax({
    url: "/somePage/",
    handErrorLocally: true
}).done(function () {
    alert("good");
}).fail(function () {
    alert("fail");
});

Или пусть глобальный обработчик позаботится:

$.ajax({
    url: "/somePage/"
}).done(function () {
    alert("good");
});

Ответ 6

Определить глобальный обработчик ошибок как функцию

function ajaxError() {
  var message = '';

  if (xhr.status == 0) {
    message = 'You are offline!\n Please check your network.';
  }
  .....
}

И создайте оболочку jQuery.ajax:

function doAjax(url, fnError) {
  jQuery.ajax(url, {
    error: fnError || defaultErrorHandler 
  })
}

Теперь используйте эту оболочку, а не по умолчанию jQuery.ajax:

doAjax('/someResource'); // defaultErrorHandler using for handle error
doAjax('/someResource', function() {...}); // custom error function using

Ответ 7

Я добавляю к ответу Тима Бэнкса, который был чрезвычайно полезен. Я просто хочу изменить тот факт, что он использует глобальную переменную и использует параметр в вызове ajax. Я по умолчанию отказался, но это можно было легко изменить.

$('html').ajaxError(function(e, xhr, settings, exception) {
    if (xhr.status == 404) {
        alert("html error callback");    
    }
});

$.ajax({
    url: "missing.html",
    global: true
});

Я отредактировал свой ответ, чтобы использовать глобальный параметр, который решает, следует ли распространять глобальный обработчик событий