AngularJS ile global Ajax hata işleyicisi


82

Web sitem% 100 jQuery iken, bunu yapardım:

$.ajaxSetup({
    global: true,
    error: function(xhr, status, err) {
        if (xhr.status == 401) {
           window.location = "./index.html";
        }
    }
});

401 hataları için genel bir işleyici ayarlamak için. Şimdi, (REST) ​​isteklerimi sunucuya yapmak için $resourceve ile birlikte angularjs kullanıyorum $http. Benzer şekilde küresel bir hata işleyiciyi açısal ile ayarlamanın bir yolu var mı?



1
Hayır, uygulama için genel bir 401 hata işleyicisi yapmak istiyoruz
cricardol

lol, ne istediğinizi düşündünüz mü, ancak farklı bir http statüsü ile (bunu değiştirebilirsiniz)? Her neyse, pkozlowski.opensource cevabı gösterileri bunu yapmak için nasıl
MilkyWayJoe

Hayır, daha çok
Justen'ın cevabına benziyor

Yanıtlar:


97

Ayrıca köşeli bir web sitesi oluşturuyorum ve küresel 401 yönetimi için aynı engelle karşılaştım. Bu blog gönderisine rastladığımda http interceptor kullanmaya başladım. Belki sen de benim kadar faydalı bulacaksın.

"AngularJS (veya benzeri) tabanlı uygulamada kimlik doğrulama." , espeo yazılımı

DÜZENLEME: nihai çözüm

angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives'], function ($routeProvider, $locationProvider, $httpProvider) {

    var interceptor = ['$rootScope', '$q', function (scope, $q) {

        function success(response) {
            return response;
        }

        function error(response) {
            var status = response.status;

            if (status == 401) {
                window.location = "./index.html";
                return;
            }
            // otherwise
            return $q.reject(response);

        }

        return function (promise) {
            return promise.then(success, error);
        }

    }];
    $httpProvider.responseInterceptors.push(interceptor);

4
$ Q.reject (yanıt); durum == 401 olduğunda, gürültülü bir açısal hatayı önlemek için
s_t_e_v_e

1
@daniellmb. Değişir. Aslında başka bir sayfaya gitmek istiyorsanız, sadece görünümü değiştirmek değil, o zaman gerçekten $ window kullanmalısınız. Giriş sayfanız sadece açısal olarak başka bir görünüm ve denetleyiciyse, $ location.path
uriDium

1
@uriDium, benim amacım açısal olarak sağlanan nesneleri kullanmaktı, böylece alay edip test edebilirsiniz.
daniellmb

22
$ httpProvider.responseInterceptors artık kullanımdan kaldırılmıştır. Docs.angularjs.org/api/ng.$http#description_interceptors adresine bakın .
quartzmo

1
Başarılı bir şekilde geri dönmeniz gerekir, return response || $q.when(response);böylece yanıt boşsa, o zaman bir promise nesnesi de döndürülür.
Ashish Gaur

77

Lütfen responseInterceptors'ın Angular 1.1.4 ile kullanımdan kaldırıldığını unutmayın. Aşağıda , durdurucuları uygulamanın yeni yolunu gösteren, resmi belgelere dayanan bir alıntı bulabilirsiniz .

$provide.factory('myHttpInterceptor', function($q, dependency1, dependency2) {
  return {
    'response': function(response) {
      // do something on success
      return response || $q.when(response);
    },

   'responseError': function(rejection) {
      // do something on error
      if (canRecover(rejection)) {
        return responseOrNewPromise;
      }
      return $q.reject(rejection);
    }
  };
});

$httpProvider.interceptors.push('myHttpInterceptor');

Coffeescript kullanarak projemde şöyle görünüyor:

angular.module("globalErrors", ['appStateModule']).factory "myHttpInterceptor", ($q, $log, growl) ->
  response: (response) ->
    $log.debug "success with status #{response.status}"
    response || $q.when response

  responseError: (rejection) ->
    $log.debug "error with status #{rejection.status} and data: #{rejection.data['message']}"
    switch rejection.status
      when 403
        growl.addErrorMessage "You don't have the right to do this"
      when 0
        growl.addErrorMessage "No connection, internet is down?"
      else
        growl.addErrorMessage "#{rejection.data['message']}"

    # do something on error
    $q.reject rejection

.config ($provide, $httpProvider) ->
  $httpProvider.interceptors.push('myHttpInterceptor')

Ancak yanıt olarak xhr verisine veya başka yararlı bilgiye sahip olmayacaksınızError interceptor. Kurtarılabilir olup olmadığına karar vermek bile kullanılamaz.
zw0rk

1
@ zw0rk Alacaksın ... içini responseError, rejectionher ihtiyacınız vardır.
Langdon

Bu son satır $httpProvider...bir config()bloğa mı sarılı ?
delwin

gerçekten de, Coffeescript kullanarak projemde nasıl yaptığımı göstermek için cevabımı düzenledim. Javascript'te tercih ediyorsanız, js2coffee.org'u kullanın .
MikeR

İşlevin responsealtındaki tüm referansların responseErroraslında referans rejectionolması gerekmez (veya parametrenin adı değiştirilmiş olabilir responsemi?
Adam Nofsinger

16

<script type="text/javascript" src="../js/config/httpInterceptor.js" ></script>Bu içeriğe sahip dosyayı oluşturun :

(function(){
  var httpInterceptor = function ($provide, $httpProvider) {
    $provide.factory('httpInterceptor', function ($q) {
      return {
        response: function (response) {
          return response || $q.when(response);
        },
        responseError: function (rejection) {
          if(rejection.status === 401) {
            // you are not autorized
          }
          return $q.reject(rejection);
        }
      };
    });
    $httpProvider.interceptors.push('httpInterceptor');
  };
  angular.module("myModule").config(httpInterceptor);
}());

@ThilakRaj yukarıdaki kod her http talebinde çalışmalıdır. Öyleyse, Chrome'da olması gerektiği gibi çalışıp çalışmadığını kontrol etmek için biri "geri dönüş" satırında ve diğeri "$ q.reject" de olmak üzere iki kesme noktası oluşturun.
Jan-Terje Sørensen
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.