Обработка ошибок jQuery Ajax для игнорирования прерванного
Я хочу иметь глобальный метод обработки ошибок для вызовов ajax, это то, что у меня есть сейчас:
$.ajaxSetup({
error: function (XMLHttpRequest, textStatus, errorThrown) {
displayError();
}
});
мне нужно игнорировать ошибку aborted
. errorThrown
null и textStatus
is error
. Как проверить aborted
?
9 ответов
мне пришлось иметь дело с тем же прецедентом сегодня. Приложение, над которым я работаю, имеет эти длительные вызовы ajax, которые могут быть прерваны 1) пользователь переходит или 2) какой-то временный сбой соединения/сервера. Я хочу, чтобы обработчик ошибок запускался только для сбоя соединения / сервера, а не для пользователя, переходящего.
Я сначала попробовал ответить Alastair Pitts, но это не сработало, потому что как прерванные запросы, так и сбой соединения установили код состояния и readyState в 0. Следующий, Я попробовал ответ зиппля; также не сработало, потому что в обоих случаях ответа не дается, следовательно, нет заголовка.
единственное решение, которое сработало для меня, - установить прослушиватель для window.onbeforeunload, который задает глобальную переменную, указывающую, что страница была выгружена. Обработчик ошибок может проверить и вызвать обработчик ошибок только в том случае, если страница не была выгружена.
var globalVars = {unloaded:false};
$(window).bind('beforeunload', function(){
globalVars.unloaded = true;
});
...
$.ajax({
error: function(jqXHR,status,error){
if (globalVars.unloaded)
return;
}
});
В современном jQuery вы можете просто проверить, если request.statusText
равна 'abort'
:
error: function (request, textStatus, errorThrown) {
if (request.statusText =='abort') {
return;
}
}
что-то я нашел, что когда есть прерванный запрос,status
и/или readyState
равной 0
.
в моем глобальном обработчике ошибок у меня есть проверка в верхней части метода:
$(document).ajaxError(function (e, jqXHR, ajaxSettings, thrownError) {
//If either of these are true, then it's not a true error and we don't care
if (jqXHR.status === 0 || jqXHR.readyState === 0) {
return;
}
//Do Stuff Here
});
я обнаружил, что это отлично работает для меня. Надеюсь, это поможет вам или кому-либо еще, кто сталкивается с этим :)
вы захотите посмотреть аргумент textStatus, переданный в вашу функцию ошибки. Согласно http://api.jquery.com/jQuery.ajax/, он может принимать значения "success", "notmodified", "error", "timeout", "abort"или " parsererror". "abort" - это, очевидно, то, что вы хотите проверить.
более длинные заметки здесь:jquery-gotcha-error-callback-triggered-on-xhr-abort
поскольку ответ bluecollarcoders не работает для ajax-запросов, прерванных javascript, вот мое решение:
var unloaded = false;
...
$(window).bind('beforeunload', function(){
unloaded = true;
});
$(document).ajaxError(function(event, request, settings) {
if (unloaded || request.statusText == "abort") {
return;
}
...
}
например
handler = jQuery.get("foo")
handler.abort()
теперь будет игнорироваться обработчиком ajaxError
на ответ Аластера Питтса, вы также можете сделать это, чтобы иметь более информативные сообщения:
$(document).ajaxError(function (e, jqXHR, ajaxSettings, thrownError)
{
{
if (jqXHR.status === 0)
{
alert('Not connect.\n Verify Network.');
} else if (jqXHR.status == 404)
{
alert('Requested page not found. [404]');
} else if (jqXHR.status == 500)
{
alert('Internal Server Error [500].');
} else if (exception === 'parsererror')
{
alert('Requested JSON parse failed.');
} else if (exception === 'timeout')
{
alert('Time out error.');
} else if (exception === 'abort')
{
alert('Ajax request aborted.');
} else
{
alert('Uncaught Error.\n' + jqXHR.responseText);
}
}
});
$(document).ajaxError(function(event, jqXHR, ajaxSettings, thrownError) {
if (!jqXHR.getAllResponseHeaders()) {
return;
}
});
у меня была та же проблема здесь, и то, что я сделал в качестве решения, было установить "прерывание" var непосредственно перед вызовом abort (), как показано ниже:
aborting = true;
myAjax.abort();
и показывать ошибку только в обработчике ошибок ajax-запроса, если abort неверен.
$.ajax({
[..]
error: function() {
if ( !aborting ) {
// do some stuff..
}
aborting = false;
}
});
быстрое (и грязное) решение:
if (status === 0) { // or -1 depending on where you do this
setTimeout(function() {
// error handling here
}, 2000); // 2 seconds, or use more ...
}
если состояние ошибки xhr равно 0 ( * ), установите задержка 2 секунд вокруг кода обработки ошибок, к тому времени браузер уже загрузил новый контекст страницы, и ошибка никогда не будет отображаться.
Если ошибка не была вызвана прерыванием при переходе на другую страницу, ошибка будет отображаться с некоторой задержкой.
* примечание: в зависимости от используемых библиотек и обработчика ошибок он может быть -1 вместо ноль (угловой ...) или что-то совсем другое.
важно: текст состояния может варьироваться от одного браузера к другому и использовать libs, поэтому IMHO вы не можете положиться на него, пожалуйста, дайте мне знать в комментариях, если вы найдете кросс-браузерное решение