web-dev-qa-db-ja.com

中止されたものを無視するJquery Ajaxエラー処理

私はajax呼び出しのためのグローバルエラー処理メソッドを持ちたいです、これは私が今持っているものです:

$.ajaxSetup({
  error: function (XMLHttpRequest, textStatus, errorThrown) {
    displayError();
  }
});

abortedのエラーを無視する必要があります。 errorThrownはnull、textStatuserrorです。 abortedを確認するにはどうすればよいですか?

77
Shawn Mclean

今日は同じユースケースに対処しなければなりませんでした。私が取り組んでいるアプリには、1)ユーザーが別の場所に移動するか、2)一時的な接続/サーバーの何らかの障害によって中断される可能性のある、長時間実行されるAjax呼び出しがあります。エラーハンドラーを接続/サーバーの障害に対してのみ実行し、移動するユーザーに対しては実行しないようにします。

最初にAlastair Pittsの回答を試しましたが、リクエストの中止と接続障害の両方がステータスコードとreadyStateを0に設定したため、うまくいきませんでした。次に、siepplの回答を試しました。また、どちらの場合も応答が返されず、ヘッダーも返されないため、機能しませんでした。

私のために働いた唯一の解決策は、window.onbeforeunloadのリスナーを設定することです。これは、ページがアンロードされたことを示すグローバル変数を設定します。エラーハンドラーは、ページがアンロードされていない場合にのみ、エラーハンドラーをチェックして呼び出すことができます。

var globalVars = {unloaded:false};
$(window).bind('beforeunload', function(){
    globalVars.unloaded = true;
});
...
$.ajax({
    error: function(jqXHR,status,error){
        if (globalVars.unloaded)
            return;
    }
});
51
bluecollarcoder

最新のjQueryでは、request.statusText'abort'と等しいかどうかを確認できます。

error: function (request, textStatus, errorThrown) {
    if (request.statusText =='abort') {
        return;
    }
}
40
Udi

私が見つけたのは、リクエストが中止されたとき、statusreadyState0

私のグローバルエラーハンドラでは、メソッドの上部にチェックがあります。

$(document).ajaxError(function (e, jqXHR, ajaxSettings, thrownError) {
    //If either of these are true, then it's not a true error and we don't care
    if (jqXHR.status === 0 || jqXHR.readyState === 0) {
        return;
    }

    //Do Stuff Here
});

これは私にとって完璧に機能することがわかりました。これがあなた、またはこれに出くわす誰かに役立つことを願っています:)

21
Alastair Pitts

エラー関数に渡されたtextStatus引数を確認する必要があります。 http://api.jquery.com/jQuery.ajax/ によると、「success」、「notmodified」、「error」、「timeout」、「abort」、または「parsererror」。 「中止」は、明らかにあなたがチェックしたいものです。

ここに長いメモ: jquery-gotcha-error-callback-triggered-on-xhr-abort

10
Paul Rademacher

Bluecollarcodersの答えは、javascriptによって中止されたajaxリクエストに対して機能しないため、ここに私の解決策があります。

var unloaded = false;
...
$(window).bind('beforeunload', function(){
    unloaded = true;
});


$(document).ajaxError(function(event, request, settings) {
    if (unloaded || request.statusText == "abort") {
        return;
    }
    ...
}

例えば.

handler = jQuery.get("foo")
handler.abort()

これで、ajaxErrorハンドラーによって無視されます

4
Sano J

Alastair Pitts'a answer に基づいて、より有益なメッセージを得るためにこれを行うこともできます。

$(document).ajaxError(function (e, jqXHR, ajaxSettings, thrownError)
{
    {
        if (jqXHR.status === 0)
        {
            alert('Not connect.\n Verify Network.');
        } else if (jqXHR.status == 404)
        {
            alert('Requested page not found. [404]');
        } else if (jqXHR.status == 500)
        {
            alert('Internal Server Error [500].');
        } else if (exception === 'parsererror')
        {
            alert('Requested JSON parse failed.');
        } else if (exception === 'timeout')
        {
            alert('Time out error.');
        } else if (exception === 'abort')
        {
            alert('Ajax request aborted.');
        } else
        {
            alert('Uncaught Error.\n' + jqXHR.responseText);
        }
    }
});
3
$(document).ajaxError(function(event, jqXHR, ajaxSettings, thrownError) {

    if (!jqXHR.getAllResponseHeaders()) {
        return;
    }           
}); 
2
sieppl

迅速な(そして汚い)ソリューション:

if (status === 0) { // or -1 depending on where you do this
  setTimeout(function() {
    // error handling here
  }, 2000); // 2 seconds, or use more ...
}

xhrエラーステータスが0(*)の場合、エラー処理コードの前後に2秒のdelayを設定します。その時点までにブラウザーは既に新しいページコンテキストをロードしており、エラーは表示されません。

エラーが別のページに移動することによるアボートによるものではない場合、エラーは少し遅れて表示されます。

*注意:使用するライブラリと、使用するエラーハンドラによっては、ゼロ(Angular ...)または完全に他の何かの代わりに-1になる場合があります。

重要:ステータステキストはブラウザごとに異なる場合があり、ライブラリを使用しているため、信頼できない私見です。クロスブラウザソリューションを見つけた場合は、コメントでお知らせください。

0

私はここで同じ問題を抱えていましたが、解決策として私がやったことは、以下のように、abort()の呼び出しの直前に「中止」変数を設定することでした:

aborting = true;
myAjax.abort();

abortがtrueでない場合、ajaxリクエストのエラーハンドラーでエラーのみを表示します。

$.ajax({
    [..]
    error: function() {
        if ( !aborting ) {
            // do some stuff..
        }
        aborting = false;
    }
});
0
Diego Malone

Ajaxリクエストを手動で中止した場合、次のようにできます。

var xhr;
function queryData () {
    if (xhr) {
      // tag it's been aborted
      xhr.hasAborted = true;

      // manually canceled request
      xhr.abort();
    }

    xhr = $.ajax({
        url: '...',
        error: function () {
            if (!xhr.hasAborted) {
                console.log('Internal Server Error!');
            }
        },
        complete: function () {
           xhr = null;
        }
    });
}
0
Sky