web-dev-qa-db-fra.com

Comment utiliser l'intercepteur angularJS pour intercepter uniquement des requêtes http spécifiques?

Je sais comment intercepter TOUTES les demandes, mais je veux seulement intercepter les demandes de mes ressources.

Est-ce que quelqu'un sait comment faire ça?

services.config(['$httpProvider',function($httpProvider) {
    $httpProvider.interceptors.Push('myHttpInterceptor');
}]);

services.factory("userPurchased", function ($resource) {
    return $resource("/api/user/purchases/:action/:item", 
        {}, 
        {
            'list': {method: 'GET', params: {action: 'list'}, isArray: false},
            'save': {method: 'PUT', params: {item: '@item'}},
            'remove': {method: 'DELETE', params: {item: '@item'}},
        }
    );
});

services.factory('myHttpInterceptor', function($q,$rootScope) {
    // $rootScope.showSpinner = false;
    return {

      response: function(response) {
        $rootScope.showSpinner = false;
        // do something on success
        console.log('success');
        console.log('status', response.status);
        //return response;
        return response || $q.when(response);
      },

     responseError: function(response) {
        // do something on error
        $rootScope.showSpinner = true;
        console.log('failure');
        console.log('status', response.status)
        //return response;
        return $q.reject(response);
      }
    };
  });
27
jrutter

Si vous souhaitez intercepter uniquement les demandes provenant de ressources spécifiques, vous pouvez utiliser la propriété interceptor facultative de l'action $request. Documentation angulaire voir ici (Utilisation> actions)

JavaScript

angular.module('app', ['ngResource']).
  factory('resourceInterceptor', function() {
    return {
      response: function(response) {
        console.log('response intercepted: ', response);
      }
    }
  }).
  factory('resourceService', ['$resource', 'resourceInterceptor', function($resource, resourceInterceptor) {
    return $resource(":name", 
        {}, 
        {
            'list': {method: 'GET', isArray: false, interceptor: resourceInterceptor}
        }
    );
  }]).
  run(['resourceService', '$http', function(resourceService, $http) {
    resourceService.list({name: 'list.json'}); // <= intercepted
    $http.get('list.json'); // <= not intercepted
  }]);

Plunker: http://plnkr.co/edit/xjJH1rdJyB6vvpDACJOT?p=preview

23
Vadim

La seule façon pour moi de le faire consiste à filtrer les demandes que vous souhaitez dans le gestionnaire de réponses.

par exemple.

...
response: function(response) {
    if(response.config.url.startsWith('/api/')) {
        //Do your custom processing here
    }

    return response;
}
...

Polyfill pour string.startsWith ()

//Taken from http://stackoverflow.com/questions/646628/javascript-startswith
if (typeof(String.prototype.startsWith) === 'undefined') {
    String.prototype.startsWith = function(str) {
        return this.slice(0, str.length) === str;
    };
}
23
rob

Ma méthode préférée consiste à utiliser un intercepteur HTTP qui remplace un en-tête d'autorisation "magique" par le jeton OAuth actuel. Le code ci-dessous est spécifique à OAuth, mais y remédier est un exercice simple pour le lecteur.

// Injects an HTTP interceptor that replaces a "Bearer" authorization header
// with the current Bearer token.
module.factory('oauthHttpInterceptor', function (OAuth) {
  return {
    request: function (config) {
      if (config.headers.Authorization === 'Bearer') {
        config.headers.Authorization = 'Bearer ' + btoa(OAuth.accessToken);
      }
      return config;
    }
  };
});

module.config(function ($httpProvider) {
  $httpProvider.interceptors.Push('oauthHttpInterceptor');
});
0
Ben Walding

Je viens de rencontrer un problème où googleapis utilise également un en-tête Authorization et renvoie une réponse 401 car le JWT que j'utilise sur mon serveur n'est pas valide pour leur serveur (évidemment), et mon code a été configuré pour supprimer automatiquement mon jeton et redirigez la personne vers la page de connexion. (Cela n'a pas été écrit très bien, car TOUTE réponse 401 déconnecterait mon utilisateur).

Je viens de trouver cette solution dans ma méthode request dans l'intercepteur, qui, je pense, fonctionne plutôt bien:

.service('authInterceptor', ["$q", "$location", "tokenService", function($q, $location, tokenService){
    this.request = function(config) {
//        console.log($location.Host());
        var token = tokenService.getToken();
        if(token && config.url.indexOf($location.Host()) > -1) {
            config.headers = config.headers || {};
            config.headers.Authorization = "Bearer " + token
        }
        return config
    }

    this.responseError = function(response) {
//        console.log(response.config.url)
        if (response.status === 401) {
            tokenService.removeToken();
            $location.path('/login')
        }
        return $q.reject(response);
    }
}])

La méthode request vérifie si j'ai un jeton dans le stockage localETsi l'URL de la demande est envoyée au même hôte (que je reçois de $location.Host()) que celui sur lequel ma page est affichée. Cela fonctionne pour localhost ainsi que pour l’URL sur laquelle je déploie mon site.

Je n’ai pas fait beaucoup de tests avec cela, donc si quelqu'un trouve une faille dans ceci, faites-le moi savoir :)

0
bobbyz
/**object single interceptor**/ 
 function SingleCallInterceptor(callbacks){

    this.receive=function(response) {

      switch (response.status) {

        case 200:

          callbacks.success(apiResponse);

          break;

        default :

          callbacks.error(response);
      }

    }

  }


var successfn=function(response){  //i have my response}

var errorfn=function(response){  //i have my error}

var responseInterceptor=new SingleCallInterceptor({success:successfn,error:errorfn});

        $http({

        url: "www.itsdirtysolutioniknow.it,

        method: "GET",

        dataType: "JSONP",

      }).then(responseInterceptor.receive,responseInterceptor.receive);
0
dnocode

Par défaut, Angular envoie et reçoit les en-têtes application/json. Vous pouvez l'obtenir sur l'en-tête de réponse HTTP comme suit: 

services.config(['$httpProvider',function($httpProvider) {
    $httpProvider.interceptors.Push('myHttpInterceptor');
}]);

services.factory("userPurchased", function ($resource) {
    return $resource("/api/user/purchases/:action/:item", 
        {}, 
        {
            'list': {method: 'GET', params: {action: 'list'}, isArray: false},
            'save': {method: 'PUT', params: {item: '@item'}},
            'remove': {method: 'DELETE', params: {item: '@item'}},
        }
    );
});

services.factory('myHttpInterceptor', function($q,$rootScope) {
    // $rootScope.showSpinner = false;
    return {

      response: function(response) {
        // use this line to if you are receiving json, else use xml or any other type
        var isJson = response.config.headers.Accept.indexOf('json')>-1;
        $rootScope.showSpinner = false;
        // do something on success
        console.log('success');
        console.log('status', response.status);
        //return response;
        return response || $q.when(response);
      },

     responseError: function(response) {
        // use this line to if you are receiving json, else use xml or any other type
        var isJson = response.config.headers.Accept.indexOf('json')>-1;
        // do something on error
        $rootScope.showSpinner = true;
        console.log('failure');
        console.log('status', response.status)
        //return response;
        return $q.reject(response);
      }
    };
  });
0
Yacine