JQuery Ajax - Cara Mendeteksi kesalahan Koneksi Jaringan saat melakukan panggilan Ajax

91

Saya memiliki beberapa kode JQuery Javascript yang melakukan panggilan Ajax ke server setiap 5 menit, itu untuk menjaga sesi server tetap hidup dan membuat pengguna tetap masuk. Saya menggunakan $.ajax()metode di JQuery. Fungsi ini tampaknya memiliki properti 'error' yang saya coba gunakan jika koneksi internet pengguna terputus sehingga skrip KeepAlive terus berjalan. Saya menggunakan kode berikut:

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);
        }
    });
}

Ketika saya menjalankannya, saya akan mendapatkan popup 'Sukses' di layar dalam kotak peringatan setiap 10 detik yang tidak masalah. Namun, segera setelah saya mencabut kabel jaringan, saya tidak mendapatkan apa-apa, saya mengharapkan fungsi kesalahan dipanggil dan melihat kotak peringatan 'Kegagalan', tetapi tidak ada yang terjadi.

Apakah saya benar dalam mengasumsikan bahwa fungsi 'kesalahan' hanya untuk kode status non '200' yang dikembalikan dari server? Apakah ada cara untuk mendeteksi masalah koneksi jaringan saat melakukan panggilan Ajax?

Sunday Ironfoot
sumber
Apakah Anda mencabut kabel jaringan klien atau kabel jaringan server?
Jeff Sternal
Apakah Anda terus mendapatkan peringatan 'berhasil' setelah mencabut koneksi Anda?
Wilkins
3
@Jeff - Hilangnya koneksi internet di sisi klien yang menyebabkan masalah. Tidak dapat dipercaya ini sebenarnya terjadi karena beberapa klien menggunakan aplikasi dengan koneksi nirkabel cerdik yang terus putus. Ada pepatah "Jangan pernah meremehkan kemampuan pengguna akhir untuk menemukan cara untuk merusak aplikasi Anda", pasti berlaku di sini :-)
Sunday Ironfoot
@qwertypants - Tidak, tidak ada yang terjadi setelah koneksi internet terputus (mis. mencabut kabel). Meskipun percobaan $ .ajax dilakukan, saya dapat melihatnya di Firebug.
Ironfoot Minggu
Apakah ada cara untuk mengatur waktu untuk percobaan koneksi?
Axk

Jawaban:

99
// 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
Craneum
sumber
4
Ini harus menjadi jawaban yang diterima. Dalam fungsi error yang Anda berikan ke $ .ajax, parameter pertama menyediakan semua jenis informasi status. Ia melakukannya meskipun Anda tidak menyetel batas waktu.
Mike Spear
Dan untuk melakukan hal yang sama dengan formulir ajax: <form ... data-ajax-failure="YourMethod" ...></form>dan pada metode Andafunction YourMethod(XMLHttpRequest) { ..same code... }
Matthieu Charbonnier
1
Untuk informasi lebih lanjut, XMLHttpRequest.readyStatelihat ajax_xmlhttprequest_response.asp
stomy
13

Anda harus menambahkan: di timeout: <number of miliseconds>,suatu tempat di dalam $.ajax({}). Juga, cache: false,mungkin membantu dalam beberapa skenario.

$ .ajax didokumentasikan dengan baik , Anda harus memeriksa opsi di sana, mungkin menemukan sesuatu yang berguna.

Semoga berhasil!

Krule
sumber
1
ada banyak hal yang sama sekali tidak didokumentasikan di Ajax dan entah bagaimana tersembunyi :(
Espanta
9

Karena saya tidak dapat menduplikasi masalah, saya hanya dapat menyarankan untuk mencoba dengan batas waktu pada panggilan ajax. Di jQuery Anda dapat mengaturnya dengan $ .ajaxSetup (dan ini akan global untuk semua panggilan $ .ajax Anda) atau Anda dapat mengaturnya secara khusus untuk panggilan Anda seperti ini:

$.ajax({
    type: 'GET',
    url: 'http://www.mywebapp.com/keepAlive',
    timeout: 15000,
    success: function(data) {},
    error: function(XMLHttpRequest, textStatus, errorThrown) {}
})

JQuery akan mendaftarkan batas waktu 15 detik pada panggilan Anda; setelah itu tanpa kode respons http dari server, jQuery akan menjalankan panggilan balik kesalahan dengan nilai textStatus disetel ke "batas waktu". Dengan ini Anda setidaknya dapat menghentikan panggilan ajax tetapi Anda tidak akan dapat membedakan masalah jaringan yang sebenarnya dari hilangnya koneksi.

Marco Z
sumber
3

Apa yang saya lihat dalam kasus ini adalah jika saya menarik kabel jaringan mesin klien dan membuat panggilan, penangan sukses ajax dipanggil (mengapa, saya tidak tahu), dan parameter datanya adalah string kosong. Jadi jika Anda memfaktorkan penanganan kesalahan yang sebenarnya, Anda dapat melakukan sesuatu seperti ini:

function handleError(jqXHR, textStatus, errorThrown) {
    ...
}

jQuery.ajax({
    ...
    success: function(data, textStatus, jqXHR) {
        if (data == "") handleError(jqXHR, "clientNetworkError", "");
    },
    error: handleError
});
Geoff
sumber
1

Jika Anda membuat panggilan lintas domain gunakan Jsonp. kalau tidak kesalahan tidak dikembalikan.

Swapnil Rebello
sumber
0

MENGGUNAKAN

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.');
    }

};

(lebih banyak kode di bawah - UPLOAD GAMBAR CONTOH)

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();
 }
 };
MalucOJonnes
sumber
-1

inilah yang saya lakukan untuk memberi tahu pengguna jika jaringan mereka mati atau setelah pembaruan halaman gagal:

  1. Saya memiliki div-tag di halaman tempat saya memasukkan waktu saat ini dan memperbarui tag ini setiap 10 detik. Ini terlihat seperti ini:<div id="reloadthis">22:09:10</div>

  2. Di akhir fungsi javascript yang memperbarui waktu di tag-div, saya meletakkan ini (setelah waktu diperbarui dengan AJAX):

    var new_value = document.getElementById('reloadthis').innerHTML;
    var new_length = new_value.length;
    if(new_length<1){
        alert("NETWORK ERROR!");
    }
    

Itu dia! Anda dapat mengganti bagian peringatan dengan apapun yang Anda inginkan, tentu saja. Semoga ini membantu.

kummik
sumber
-6

Sudahkah kamu mencobanya?

$(document).ajaxError(function(){ alert('error'); }

Itu harus menangani semua AjaxErrors. Saya menemukannya di sini . Di sana Anda juga dapat menemukan kemungkinan untuk menulis kesalahan ini ke konsol firebug Anda.

MaikL80
sumber