jQuery Ajax-Ajax呼び出しを行うときにネットワーク接続エラーを検出する方法


91

5分ごとにサーバーへのAjax呼び出しを行うJavascript JQueryコードがいくつかあります。これは、サーバーセッションを存続させ、ユーザーをログイン状態に保つためです。私は$.ajax()JQueryでメソッドを使用しています。この関数には、ユーザーのインターネット接続がダウンしてKeepAliveスクリプトが引き続き実行される場合に使用しようとしている「エラー」プロパティがあるようです。次のコードを使用しています。

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呼び出しを行うときにネットワーク接続の問題を検出する方法はありますか?


クライアントのネットワークケーブルまたはサーバーのネットワークケーブルを取り外しましたか?
ジェフスターナル

接続を外した後も引き続き「成功」アラートが表示されますか?
ウィルキンス

3
@ジェフ-問題を引き起こしているのは、クライアント側でのインターネット接続の喪失です。信じられないことに、これは実際に起こっており、一部のクライアントは、途方に暮れ続ける危険なワイヤレス接続でアプリを使用しています。「エンドユーザーがアプリケーションを破壊する方法を見つける能力を過小評価しないでください」という格言がありますが、間違いなくここに当てはまります:-)
日曜日Ironfoot

@qwertypants-いいえ、インターネット接続が失われると何も起こりません(例:ケーブルの取り外し)。$ .ajaxの試みは行われましたが、Firebugで確認できます。
日曜日のアイアンフット

接続試行のタイムアウトを設定する方法はありますか?
axk 2009年

回答:


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
これは受け入れられる答えになるはずです。$ .ajaxに提供するエラー関数では、最初のパラメーターはあらゆる種類のステータス情報を提供します。タイムアウトを設定しなくても、そうします。
マイクスピア

そして、AJAXフォームと同じことをします<form ... data-ajax-failure="YourMethod" ...></form>と、あなたの方法にfunction YourMethod(XMLHttpRequest) { ..same code... }
マチューシャルボニエ

1
詳細についてXMLHttpRequest.readyStateは、ajax_xmlhttprequest_response.asp
stomyを

13

追加する必要があります:timeout: <number of miliseconds>,内のどこかに$.ajax({})。また、cache: false,いくつかのシナリオで役立つ場合があります。

$ .ajaxは十分に文書化されています。そこでオプションを確認する必要があります。何か役立つものが見つかるかもしれません。

幸運を!


1
Ajaxにはまったく文書化されていないものが多く、どういうわけか隠されています:(
Espanta

9

私は問題を再現できないので、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呼び出しを停止できますが、実際のネットワークの問題と接続の喪失を区別することはできません。


3

この場合、クライアントマシンのネットワークケーブルをプルして呼び出しを行うと、ajax成功ハンドラーが呼び出され(理由はわかりません)、データパラメーターは空の文字列になります。したがって、実際のエラー処理を除外すると、次のようなことができます。

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

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


0

使用する

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

-1

ネットワークがダウンした場合、またはページの更新に失敗した場合にユーザーに警告するために私がしたことは次のとおりです。

  1. ページにdivタグがあり、現在の時刻を入力して、このタグを10秒ごとに更新しています。次のようになります。<div id="reloadthis">22:09:10</div>

  2. divタグの時間を更新するJavaScript関数の最後に、これを配置します(時間はAJAXで更新された後)。

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

それでおしまい!もちろん、アラート部分を好きなように置き換えることができます。お役に立てれば。


-6

これを試しましたか?

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

これですべてのAjaxErrorsが処理されます。ここで見つけまし。そこで、これらのエラーをFirebugコンソールに書き込む可能性もあります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.