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);
}
};
});
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
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;
};
}
/**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);
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');
});
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);
}
};
});
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 :)