Mam kod JavaScript JQuery, który wykonuje wywołanie Ajax do serwera co 5 minut, ma to na celu utrzymanie sesji serwera i zalogowanie użytkownika. Używam $.ajax()
metody w JQuery. Wydaje się, że ta funkcja ma właściwość „błąd”, której próbuję użyć w przypadku awarii połączenia internetowego użytkownika, aby skrypt KeepAlive nadal działał. Używam następującego kodu:
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);
}
});
}
Kiedy go uruchomię, co 10 sekund będzie pojawiać się wyskakujące okienko „Sukces” w oknie z ostrzeżeniem. Jednak jak tylko odłączę kabel sieciowy, nic się nie dzieje, spodziewałem się wywołania funkcji błędu i wyświetlenie komunikatu „Awaria”, ale nic się nie dzieje.
Czy mam rację zakładając, że funkcja „błąd” dotyczy tylko kodów statusu innych niż „200” zwracanych z serwera? Czy istnieje sposób na wykrycie problemów z połączeniem sieciowym podczas wykonywania połączenia Ajax?
źródło
Odpowiedzi:
// 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
źródło
<form ... data-ajax-failure="YourMethod" ...></form>
i na swojej metodziefunction YourMethod(XMLHttpRequest) { ..same code... }
XMLHttpRequest.readyState
patrz ajax_xmlhttprequest_response.aspWystarczy dodać:
timeout: <number of miliseconds>,
gdzieś w środku$.ajax({})
. Ponadto,cache: false,
może pomóc w kilku scenariuszy.$ .ajax jest dobrze udokumentowane , powinieneś sprawdzić tam opcje, może znajdziesz coś przydatnego.
Powodzenia!
źródło
Ponieważ nie mogę powielić problemu, mogę tylko zasugerować, aby spróbować z przekroczeniem limitu czasu w wywołaniu Ajax. W jQuery możesz ustawić to za pomocą $ .ajaxSetup (i będzie to globalne dla wszystkich twoich wywołań $ .ajax) lub możesz ustawić to specjalnie dla swojego wywołania w następujący sposób:
$.ajax({ type: 'GET', url: 'http://www.mywebapp.com/keepAlive', timeout: 15000, success: function(data) {}, error: function(XMLHttpRequest, textStatus, errorThrown) {} })
JQuery zarejestruje 15-sekundowy limit czasu połączenia; po tym bez kodu odpowiedzi http z serwera jQuery wykona wywołanie zwrotne błędu z wartością textStatus ustawioną na „timeout”. Dzięki temu możesz przynajmniej zatrzymać połączenie Ajax, ale nie będziesz w stanie odróżnić rzeczywistych problemów z siecią od utraty połączeń.
źródło
W tym przypadku widzę, że jeśli wyciągnę kabel sieciowy maszyny klienta i wykonam wywołanie, zostanie wywołana procedura obsługi AJAX (dlaczego, nie wiem), a parametr danych jest pustym ciągiem. Więc jeśli weźmiesz pod uwagę rzeczywistą obsługę błędów, możesz zrobić coś takiego:
function handleError(jqXHR, textStatus, errorThrown) { ... } jQuery.ajax({ ... success: function(data, textStatus, jqXHR) { if (data == "") handleError(jqXHR, "clientNetworkError", ""); }, error: handleError });
źródło
Jeśli wykonujesz międzydomenę, wywołaj metodę Use Jsonp. w przeciwnym razie błąd nie zostanie zwrócony.
źródło
POSŁUGIWAĆ SIĘ
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.'); } };
(więcej kodu poniżej - PRZEŚLIJ PRZYKŁAD OBRAZU)
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(); } };
źródło
oto, co zrobiłem, aby ostrzec użytkownika w przypadku awarii sieci lub niepowodzenia aktualizacji strony:
Mam na stronie znacznik DIV, w którym umieszczam aktualny czas i aktualizuję ten tag co 10 sekund. Wygląda mniej więcej tak:
<div id="reloadthis">22:09:10</div>
Na końcu funkcji javascript, która aktualizuje czas w znaczniku div, umieściłem to (po aktualizacji czasu za pomocą AJAX):
var new_value = document.getElementById('reloadthis').innerHTML; var new_length = new_value.length; if(new_length<1){ alert("NETWORK ERROR!"); }
Otóż to! Oczywiście możesz zastąpić część ostrzegawczą czymkolwiek zechcesz. Mam nadzieję że to pomoże.
źródło
Czy próbowałeś tego?
$(document).ajaxError(function(){ alert('error'); }
To powinno obsłużyć wszystkie AjaxErrors. Znalazłem to tutaj . Znajdziesz tam również możliwość zapisania tych błędów na konsoli firebuga.
źródło