2014-04-11 18 views
26

So come intercettare TUTTE le richieste, ma voglio solo intercettare le richieste dalle mie risorse.Come utilizzare l'intercettore angularJS per intercettare solo richieste HTTP specifiche?

Qualcuno sa come fare?

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

risposta

23

Se si vuole intercettare solo le richieste provenienti da risorse specifiche, è possibile utilizzare opzionale interceptor proprietà di $request azione. di angolari documentazione see here (utilizzo> azioni)

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

+0

Grazie - questo è esattamente quello che stavo cercando! – jrutter

+0

Esattamente quello di cui avevo bisogno! Grazie! –

+0

Questo non funziona quando invio più intercettori su httpProvider. Voglio chiamare solo un intercettore specifico, che sto facendo come sopra, ma il metodo di richiesta viene chiamato da tutti gli intercettori che ho registrato. – Sanket

23

L'unico modo che conosco di fare questo è per filtrare solo le richieste che si desidera nel gestore risposta.

ad es.

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

    return response; 
} 
... 

Polyfill per 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; 
    }; 
} 
+5

+1 per polyfill frammento di attribuzione – Vadim

+3

Se stai usando URL diretti, il buon vecchio 'indexOf ('/ api /')> -1' dovrebbe funzionare anche – Tukkan

+0

Questa risposta funziona solo se l'API di riposo è ben denominata usando '/ api /'. Preferisco controllare l'intestazione http per il tipo di contenuto (come XML o JSON) – Yacine

0
/**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

Fornisce solo una funzione di callback. Come si userebbe come intercettatore di chiamate http? –

0

Il mio modo preferito è quello di utilizzare un intercettore HTTP che sostituisce un colpo di testa di autorizzazione "magico" con il token OAuth corrente. Il codice sotto è specifico di OAuth, ma rimediare è un semplice esercizio per il lettore.

// 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'); 
}); 
+1

Questo in realtà non risponde alla domanda che è stata posta – Squiggle

+0

Lo fa - basta fornire un'intestazione 'Autorizzazione' di" Bearer "/" stringa magica "con le tue richieste (e nessun'altra), e l'interceptor sarà chiamato. Potresti usare la risposta accettata - e questo è probabilmente più ovvio - ma vorrai dire che stai legando quell'intercettore ovunque - mentre il metodo nel mio esempio offre indiretta. –

0

Per impostazione predefinita, invia e riceve l'applicazione/le intestazioni json. È possibile ottenere questo sulla intestazione della risposta HTTP come:

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

Ho appena imbattuto in un problema in cui googleapis anche utilizza un header Authorization, e stava gettando una risposta 401, perché il JWT che uso sul mio server non valida per il loro server (ovviamente), e il mio codice è stato impostato per rimuovere automaticamente il mio token e reindirizzare la persona alla pagina di accesso. (Non è stato scritto molto bene, dal momento che QUALUNQUE risposta 401 registrerebbe il mio utente).

Ho appena si avvicinò con questa soluzione nel mio metodo request nel intercettore, che secondo me funziona abbastanza bene:

.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); 
    } 
}]) 

I request controlli metodo se ho un gettone nella memoria locale E se il la richiesta di url viene effettuata sullo stesso host (che ottengo da $location.host()) come quella su cui viene pubblicata la mia pagina. Funziona sia per localhost che per qualsiasi URL che finisco per distribuire il mio sito.

non ho fatto molte prove con questo, quindi se qualcuno trova un difetto in questo fatemelo sapere :)

Problemi correlati