web-dev-qa-db-fra.com

Gestionnaire d'erreur global Ajax avec AngularJS

Quand mon site Web était 100% jQuery, je faisais ceci:

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

définir un gestionnaire global pour les erreurs 401. Maintenant, j'utilise angularjs avec $resource et $http faire mes demandes (REST) ​​au serveur. Est-il possible de définir de manière similaire un gestionnaire d'erreur global avec angular?

82
cricardol

Je construis également un site Web avec angular et je suis tombé sur le même obstacle pour la gestion globale 401. J'ai finalement utilisé un intercepteur http lorsque je suis tombé sur ce billet de blog. Peut-être le trouverez-vous aussi utile que je l'ai fait.

"Authentification dans les applications basées sur AngularJS (ou similaire)." , logiciel espeo

EDIT: solution finale

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);
97
Justen

Veuillez noter que les responseInterceptors sont obsolètes avec Angular 1.1.4. Vous trouverez ci-dessous un extrait basé sur le documentation officielle , montrant le nouveau moyen de mettre en œuvre des intercepteurs.

$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');

Voici comment cela se présente dans mon projet avec Coffeescript:

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')
77
MikeR

Créez le fichier <script type="text/javascript" src="../js/config/httpInterceptor.js" ></script> avec ce contenu:

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