JQuery Ajax - Cách phát hiện lỗi kết nối mạng khi thực hiện cuộc gọi Ajax


91

Tôi có một số mã Javascript JQuery thực hiện cuộc gọi Ajax đến máy chủ cứ sau 5 phút, nó để giữ cho phiên máy chủ hoạt động và giữ cho người dùng đăng nhập. Tôi đang sử dụng $.ajax()phương thức trong JQuery. Chức năng này dường như có thuộc tính 'lỗi' mà tôi đang cố gắng sử dụng trong trường hợp kết nối internet của người dùng gặp sự cố để tập lệnh KeepAlive tiếp tục chạy. Tôi đang sử dụng mã sau:

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

Khi tôi chạy nó, tôi sẽ nhận được thông báo 'Thành công' bật lên trên màn hình trong một hộp cảnh báo sau mỗi 10 giây. Tuy nhiên, ngay sau khi tôi rút cáp mạng, tôi không nhận được gì, tôi đã mong đợi hàm báo lỗi được gọi và nhìn thấy hộp cảnh báo 'Failure', nhưng không có gì xảy ra.

Tôi có đúng khi giả định rằng chức năng 'lỗi' chỉ dành cho mã trạng thái không phải '200' được trả về từ máy chủ không? Có cách nào để phát hiện sự cố kết nối mạng khi thực hiện cuộc gọi Ajax không?


Bạn đã rút cáp mạng của máy khách hoặc cáp mạng của máy chủ chưa?
Jeff Sternal

Bạn có tiếp tục nhận được cảnh báo 'thành công' sau khi rút kết nối không?
Wilkins

3
@Jeff - Việc mất kết nối Internet ở đầu máy khách là nguyên nhân gây ra sự cố. Không thể ngờ được điều này đang thực sự xảy ra khi một số khách hàng sử dụng ứng dụng với kết nối không dây khó hiểu liên tục bị rớt mạng. Có một câu nói "Đừng bao giờ đánh giá thấp khả năng của người dùng cuối trong việc tìm cách phá vỡ ứng dụng của bạn", chắc chắn đúng ở đây :-)
Chủ nhật Ironfoot

@qwertypants - Không, không có gì xảy ra khi mất kết nối internet (ví dụ: rút cáp). Mặc dù nỗ lực $ .ajax đã được thực hiện, tôi có thể thấy nó trong Firebug.
Chủ nhật Ironfoot

Có cách nào để thiết lập thời gian chờ kết nối không?
axk

Câu trả lời:


98
// 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

4
Đây phải là câu trả lời được chấp nhận. Trong hàm lỗi bạn cung cấp cho $ .ajax, tham số đầu tiên cung cấp tất cả các loại thông tin trạng thái. Nó làm như vậy ngay cả khi bạn không đặt thời gian chờ.
Mike Spear

Và để làm điều tương tự với một hình thức ajax: <form ... data-ajax-failure="YourMethod" ...></form>và trên phương pháp của bạnfunction YourMethod(XMLHttpRequest) { ..same code... }
Matthieu Charbonnier

1
Khoảng hơn XMLHttpRequest.readyStatethấy ajax_xmlhttprequest_response.asp
Stomy

13

Bạn chỉ nên thêm: timeout: <number of miliseconds>,một nơi nào đó trong $.ajax({}). Ngoài ra, cache: false,có thể hữu ích trong một số trường hợp.

$ .ajax được ghi chép đầy đủ , bạn nên kiểm tra các tùy chọn ở đó, có thể tìm thấy điều gì đó hữu ích.

Chúc may mắn!


1
có rất nhiều điều không phải ở tất cả các tài liệu trong Ajax và bằng cách nào đó ẩn :(
Espanta

9

Vì tôi không thể lặp lại vấn đề, tôi chỉ có thể đề xuất thử với thời gian chờ cho cuộc gọi ajax. Trong jQuery, bạn có thể đặt nó bằng $ .ajaxSetup (và nó sẽ là toàn cầu cho tất cả các lệnh gọi $ .ajax của bạn) hoặc bạn có thể đặt cụ thể cho cuộc gọi của mình như sau:

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

JQuery sẽ đăng ký thời gian chờ 15 giây cho cuộc gọi của bạn; sau đó mà không có mã phản hồi http từ máy chủ jQuery sẽ thực hiện lệnh gọi lại lỗi với giá trị textStatus được đặt thành "timeout". Với điều này, ít nhất bạn có thể dừng cuộc gọi ajax nhưng bạn sẽ không thể phân biệt các vấn đề mạng thực sự với việc mất kết nối.


3

Những gì tôi thấy trong trường hợp này là nếu tôi kéo cáp mạng của máy khách và thực hiện cuộc gọi, trình xử lý thành công ajax sẽ được gọi (tại sao, tôi không biết) và tham số dữ liệu là một chuỗi trống. Vì vậy, nếu bạn xác định được cách xử lý lỗi thực sự, bạn có thể làm như sau:

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

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

1

Nếu bạn đang tạo tên miền chéo, hãy gọi Use Jsonp. nếu không thì lỗi không được trả lại.


0

SỬ DỤNG

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

};

(thêm mã bên dưới - VÍ DỤ TẢI LÊN HÌNH ẢNH)

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

-1

đây là những gì tôi đã làm để cảnh báo người dùng trong trường hợp mạng của họ gặp sự cố hoặc khi cập nhật trang bị lỗi:

  1. Tôi có thẻ div trên trang mà tôi đặt thời gian hiện tại và cập nhật thẻ này sau mỗi 10 giây. Nó trông giống như sau:<div id="reloadthis">22:09:10</div>

  2. Ở cuối hàm javascript cập nhật thời gian trong thẻ div, tôi đặt điều này (sau khi thời gian được cập nhật với AJAX):

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

Đó là nó! Tất nhiên, bạn có thể thay thế phần cảnh báo bằng bất cứ thứ gì bạn muốn. Hi vọng điêu nay co ich.


-6

Bạn đã thử cái này chưa?

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

Điều đó sẽ xử lý tất cả các AjaxErrors. Tôi đã tìm thấy nó ở đây . Ở đó, bạn cũng có thể ghi những lỗi này vào bảng điều khiển firebug của mình.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.