jQuery ajax общая обработка ошибок и на индивидуальной основе - PullRequest
16 голосов
/ 03 февраля 2011

У меня есть общий обработчик ошибок 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.вместо этого хотел бы предупредить "foo":

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

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

Ответы [ 7 ]

20 голосов
/ 06 апреля 2011

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

8 голосов
/ 03 февраля 2011

Я не думаю, что вы можете контролировать это с помощью 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/

4 голосов
/ 21 октября 2016

Я думаю, что установка глобальной переменной - плохая идея, потому что вы можете иметь несколько запросов 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
})
3 голосов
/ 19 февраля 2015

Это старый вопрос, но это может быть полезно для кого-то.Проблема с этим ответом заключается в том, что у вас может быть код в глобальных обработчиках, который вам нужно выполнить.Я нашел этот другой ответ более полезным, но использование глобальных переменных не очень хорошая практика.Также у вас может быть несколько вызовов 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");
});

Или позвольте глобальному обработчику позаботиться:1012 *

3 голосов
/ 04 февраля 2011

Мы на самом деле решили это следующим образом:

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 теперь будет ссылаться на функцию одним из двух способов:

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

error: ajaxError

2) если мы хотим нацелиться на конкретную ситуацию, если она не обнаружена, перейдите к настройке по умолчанию

    error: function(xhr) {

        if (xhr.status == 404) {
            alert("local");
        }
        else {
            // revert to default
            ajaxError.apply(this, arguments);
        }
    }
2 голосов
/ 16 июля 2014

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

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
1 голос
/ 18 июля 2012

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...