15

次のような「キャンセル可能な」angularJs$http呼び出しがあります。

var defer = $q.defer()
$http.post("http://example.com/someUrl", {some: "data"}, {timeout: defer.promise})

defer.resolve()そして、いくつかのロジックがそれを必要とするため、使用してその ajax リクエストをキャンセルします。


私のコードの他の場所には、次のようなイターセプターがあります。

angular.module("services.interceptor", arguments).config(function($httpProvider) {
     $httpProvider.interceptors.push(function($q) {
        return {
          responseError: function(rejection) {
            if(rejection.status == 0) {
              alert("check your connection");
            }
           return $q.reject(rejection);
        }
      };
    });
  });
});

問題:

インターネット接続に問題がある場合、ajax はステータス 0で失敗し、インターセプターがそれをキャッチします。timeout promiseによって ajax がキャンセルされた場合、status も 0になり、インターセプターがそれをキャッチします。

responseErrorキャンセルされたのか、ハンドラーでエラーが発生したのかわかりません。

私の素朴なアプローチは、タイムアウトが次のように定義されているかどうかを確認することです。

responseError: function(rejection) {
  if(rejection.status == 0 && !rejection.config.timeout) {
    alert("check your connection");
  }
  return $q.reject(rejection);
}

そのリクエストにタイムアウト条件があることを保証するだけであり、それが原因で失敗したわけありません。しかし、何もないよりはましです。

ajaxが失敗したかキャンセルされたかを判断する実際に機能する方法はありますか?

私はAngularJs 1.1.5を使用しています

4

5 に答える 5

0

グローバル イベント オブジェクトのプロパティ タイプを文字列「abort」と照合することで、Chrome v55 でリクエストがキャンセルされたかどうかを判断できました(以下のコード)。別のページに移動すると、進行中のリクエストがキャンセルされ、responseError がトリガーされるという問題がありました。

angular.module("services.interceptor", arguments)
  .config(function($httpProvider) {
     $httpProvider.interceptors.push(function($q, $window) {
        return {
          responseError: function(rejection) {
            if($window.event.type === "abort") {
               // handle cancelled here
            } else if(rejection.status < 1) {
              alert("check your connection");
            }
           return $q.reject(rejection);
        }
      };
    });
  });
});

(また: status プロパティは、ネットワークエラーで 0 から -1 に変更されたようですので、書きましたrejection.status < 1))

于 2017-01-31T12:14:43.070 に答える