JQuery Ajax - Как обнаружить ошибку сетевого соединения при вызове Ajax
У меня есть код Javascript JQuery, который вызывает Ajax-вызов на сервере каждые 5 минут, чтобы сохранить сеанс сервера и не запустил вход пользователя. Я использую метод $.ajax()
в JQuery. Кажется, что эта функция имеет свойство "error", которое я пытаюсь использовать в случае, когда соединение с интернет-подключением отключается, чтобы KeepAlive script продолжал работать. Я использую следующий код:
var keepAliveTimeout = 1000 * 10;
function keepSessionAlive()
{
$.ajax(
{
type: 'GET',
url: 'http://www.mywebapp.com/keepAlive',
success: function(data)
{
alert('Success');
setTimeout(function()
{
keepSessionAlive();
}, keepAliveTimeout);
},
error: function(XMLHttpRequest, textStatus, errorThrown)
{
alert('Failure');
setTimeout(function()
{
keepSessionAlive();
}, keepAliveTimeout);
}
});
}
Когда я запустил его, я получу всплывающее окно "Успех" на экране в окне оповещений каждые 10 секунд, и это нормально. Однако, как только я отсоединяю сетевой кабель, я ничего не получаю, я ожидал, что функция ошибки будет вызвана и появится окно предупреждения "Сбой", но ничего не происходит.
Правильно ли я полагаю, что функция "ошибка" предназначена только для кодов статуса "200", возвращаемых с сервера? Есть ли способ обнаружить проблемы с сетевым подключением при вызове Ajax?
Ответы
Ответ 1
// start snippet
error: function(XMLHttpRequest, textStatus, errorThrown) {
if (XMLHttpRequest.readyState == 4) {
// HTTP error (can be checked by XMLHttpRequest.status and XMLHttpRequest.statusText)
}
else if (XMLHttpRequest.readyState == 0) {
// Network error (i.e. connection refused, access denied due to CORS, etc.)
}
else {
// something weird is happening
}
}
//end snippet
Ответ 2
Вы должны просто добавить: timeout: <number of miliseconds>,
где-то в пределах $.ajax({})
.
Кроме того, cache: false,
может помочь в нескольких сценариях.
$. ajax хорошо документирован, вы должны проверить там варианты, найти что-то полезное.
Удачи!
Ответ 3
Так как я не могу продублировать проблему, я могу только предложить попробовать с таймаутом на вызов ajax. В jQuery вы можете установить его с помощью $.ajaxSetup (и он будет глобальным для всех ваших вызовов $.ajax), или вы можете установить его специально для вашего вызова, например:
$.ajax({
type: 'GET',
url: 'http://www.mywebapp.com/keepAlive',
timeout: 15000,
success: function(data) {},
error: function(XMLHttpRequest, textStatus, errorThrown) {}
})
JQuery зарегистрирует 15-секундный тайм-аут на ваш звонок; после этого без http-кода ответа от сервера jQuery выполнит обратный вызов ошибки со значением textStatus, установленным в "timeout". При этом вы можете, по крайней мере, остановить вызов ajax, но не сможете отличить реальные проблемы сети от потери соединений.
Ответ 4
В этом случае я вижу, что если я вытащил сетевой кабель клиентской машины и выполнил вызов, вызывается обработчик успеха ajax (почему, я не знаю), а параметр data - пустая строка. Поэтому, если вы учитываете реальную обработку ошибок, вы можете сделать что-то вроде этого:
function handleError(jqXHR, textStatus, errorThrown) {
...
}
jQuery.ajax({
...
success: function(data, textStatus, jqXHR) {
if (data == "") handleError(jqXHR, "clientNetworkError", "");
},
error: handleError
});
Ответ 5
Если вы делаете перекрестный домен, используйте Use Jsonp. иначе ошибка не будет возвращена.
Ответ 6
ИСПОЛЬЗОВАНИЕ
xhr.onerror = function(e){
if (XMLHttpRequest.readyState == 4) {
// HTTP error (can be checked by XMLHttpRequest.status and XMLHttpRequest.statusText)
selFoto.erroUploadFoto('Erro HTTP: '+XMLHttpRequest.statusText);
}
else if (XMLHttpRequest.readyState == 0) {
// Network error (i.e. connection refused, access denied due to CORS, etc.)
selFoto.erroUploadFoto('Erro de rede:'+XMLHttpRequest.statusText);
}
else {
selFoto.erroUploadFoto('Erro desconhecido.');
}
};
(больше кода ниже - ПРИМЕР ЗАГРУЗКИ)
var selFoto = {
foto: null,
upload: function(){
LoadMod.show();
var arquivo = document.frmServico.fileupload.files[0];
var formData = new FormData();
if (arquivo.type.match('image.*')) {
formData.append('upload', arquivo, arquivo.name);
var xhr = new XMLHttpRequest();
xhr.open('POST', 'FotoViewServlet?acao=uploadFoto', true);
xhr.responseType = 'blob';
xhr.onload = function(e){
if (this.status == 200) {
selFoto.foto = this.response;
var url = window.URL || window.webkitURL;
document.frmServico.fotoid.src = url.createObjectURL(this.response);
$('#foto-id').show();
$('#div_upload_foto').hide();
$('#div_master_upload_foto').css('background-color','transparent');
$('#div_master_upload_foto').css('border','0');
Dados.foto = document.frmServico.fotoid;
LoadMod.hide();
}
else{
erroUploadFoto(XMLHttpRequest.statusText);
}
if (XMLHttpRequest.readyState == 4) {
selFoto.erroUploadFoto('Erro HTTP: '+XMLHttpRequest.statusText);
}
else if (XMLHttpRequest.readyState == 0) {
selFoto.erroUploadFoto('Erro de rede:'+XMLHttpRequest.statusText);
}
};
xhr.onerror = function(e){
if (XMLHttpRequest.readyState == 4) {
// HTTP error (can be checked by XMLHttpRequest.status and XMLHttpRequest.statusText)
selFoto.erroUploadFoto('Erro HTTP: '+XMLHttpRequest.statusText);
}
else if (XMLHttpRequest.readyState == 0) {
// Network error (i.e. connection refused, access denied due to CORS, etc.)
selFoto.erroUploadFoto('Erro de rede:'+XMLHttpRequest.statusText);
}
else {
selFoto.erroUploadFoto('Erro desconhecido.');
}
};
xhr.send(formData);
}
else{
selFoto.erroUploadFoto('');
MyCity.mensagens.push('Selecione uma imagem.');
MyCity.showMensagensAlerta();
}
},
erroUploadFoto : function(mensagem) {
selFoto.foto = null;
$('#file-upload').val('');
LoadMod.hide();
MyCity.mensagens.push('Erro ao atualizar a foto. '+mensagem);
MyCity.showMensagensAlerta();
}
};
Ответ 7
здесь, что я сделал, чтобы предупредить пользователя о том, что их сеть опустилась или при сбое обновления страницы:
-
У меня есть тег div на странице, где я помещаю текущее время и обновляю этот тег каждые 10 секунд. Это выглядит примерно так: <div id="reloadthis">22:09:10</div>
-
В конце функции javascript, которая обновляет время в div-теге, я помещаю это (после времени обновляется с помощью AJAX):
var new_value = document.getElementById('reloadthis').innerHTML;
var new_length = new_value.length;
if(new_length<1){
alert("NETWORK ERROR!");
}
Что это! Разумеется, вы можете заменить часть оповещения на все, что хотите.
Надеюсь, это поможет.
Ответ 8
Вы пробовали это?
$(document).ajaxError(function(){ alert('error'); }
Это должно обрабатывать все AjaxErrors. Я нашел здесь.
Там вы также найдете возможность записать эти ошибки в консоль firebug.