Comment utiliser angularJS interceptor pour intercepter uniquement des requêtes http spécifiques?

je sais intercepter toutes les requêtes, mais je ne veux intercepter que les requêtes de mes ressources.

est-ce que quelqu'un sait 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);
      }
    };
  });
26
demandé sur jrutter 2014-04-11 23:51:21

6 réponses

si vous voulez intercepter uniquement des requêtes provenant de ressources spécifiques, vous pouvez utiliser l'option interceptor propriété de $request action. Angulaire de la documentation 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
répondu Vadim 2014-04-11 20:23:58

la seule façon que je connaisse de le faire est de filtrer les requêtes que vous voulez dans le gestionnaire de réponse.

p.ex.

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

    return response;
}
...

Polyfill pour la chaîne.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
répondu rob 2014-04-11 19:59:52
/**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
répondu dnocode 2014-11-28 17:25:38

ma méthode préférée est d'utiliser un intercepteur HTTP qui remplace un en-tête D'autorisation" magic " par le jeton courant OAuth. Le code ci-dessous est autre spécifique, mais la correction qui 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
répondu Ben Walding 2016-05-06 02:23:28

par défaut angular envoie et reçoit des en-têtes application/json. Vous pouvez obtenir cela sur L'en-tête de réponse HTTP comme:

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
répondu Yacine 2016-07-01 13:30:23

je viens de tomber sur un problème où googleapis utilise également un en-tête Authorization , et lançait une réponse 401 parce que la JWT que j'utilise sur mon serveur n'était pas valide pour leur serveur (évidemment), et mon code a été défini pour supprimer automatiquement mon token et rediriger la personne vers la page de connexion. (Ce n'était pas très bien écrit, puisque toute réponse à la question 401 allait se déconnecter de mon utilisateur).

je viens de trouver cette solution dans ma méthode request dans l'intercepteur, que je pensez fonctionne assez 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 token dans le stockage local et si l'url de la requête est faite sur le même hôte (que j'obtiens de $location.host() ) que celui sur lequel ma page est servie. Cela fonctionne pour localhost ainsi que quelle que soit L'URL sur laquelle je finis par déployer mon site.

Je n'ai pas fait beaucoup de tests avec cela, donc si quelqu'un trouve un défaut dans ceci s'il vous plaît laissez-moi savoir :)

0
répondu bobbyz 2017-03-07 23:21:44