AngularJS Intercepta todas as respostas do $ http JSON

Eu tenho um aplicativo construído usando AngularJS e um back-end do lado do servidor que oferece todas as solicitações no formulário JSON. Toda e qualquer solicitação é agrupada em um contêiner JSON que contém uma variável de dados que contém os dados específicos da solicitação. Os outros dados, que são usados ​​para manter o estado e o controle no aplicativo, verificam erros e mensagens de êxito e verificam se há sinalizadores de session. Todas essas outras variables ​​são atendidas com EVERY request e são examinadas antes da variável de dados.

No momento, tenho um método para examinar primeiro o conteúdo da resposta JSON e depois os dados.

$http.get('something.json').success(function(response) { var data = examineJSONResponse(response); //do the data stuff }); 

Isso funciona e o examineJSONResponse dá uma olhada no código e, se houver algo errado, ele lança uma exceção e recarrega a página usando window.location.href.

Existe alguma maneira que eu possa automatizar isso dentro de AngularJS para que cada vez que uma chamada $ http é feita, então ele verifica isso e só retorna o conteúdo da variável de dados como a resposta JSON?

Você pode interceptar respostas adicionando um interceptador a $httpProvider.interceptors com Angular 1.1.4+ (veja a documentação aqui para procurar por interceptores).

Para um tipo de conteúdo específico como json, você pode potencialmente rejeitar alterações ou lançar uma exceção, mesmo que a chamada tenha sido um sucesso. Você pode modificar o response.data que também será passado para o seu código de controlador aqui:

 myModule.factory('myHttpInterceptor', function ($q) { return { response: function (response) { // do something on success if(response.headers()['content-type'] === "application/json; charset=utf-8"){ // Validate response, if not ok reject var data = examineJSONResponse(response); // assumes this function is available if(!data) return $q.reject(response); } return response; }, responseError: function (response) { // do something on error return $q.reject(response); } }; }); myModule.config(function ($httpProvider) { $httpProvider.interceptors.push('myHttpInterceptor'); }); 

NOTA: Aqui está a resposta original para versões anteriores à 1.1.4 ( responseInterceptors foram descontinuados com o Angular 1.1.4):

Talvez haja uma maneira melhor, mas acho que você pode fazer algo semelhante a este post com o interceptor de resposta http (descrito aqui ) (para um tipo de conteúdo específico como json) onde você potencialmente rejeita alterações ou lança uma exceção mesmo que a chamada tenha sido um sucesso . Você pode modificar o response.data que será passado para o código do controlador também aqui.

 myModule.factory('myHttpInterceptor', function ($q) { return function (promise) { return promise.then(function (response) { // do something on success if(response.headers()['content-type'] === "application/json; charset=utf-8"){ // Validate response if not ok reject var data = examineJSONResponse(response); // assumes this function is available if(!data) return $q.reject(response); } return response; }, function (response) { // do something on error return $q.reject(response); }); }; }); myModule.config(function ($httpProvider) { $httpProvider.responseInterceptors.push('myHttpInterceptor'); }); 

Outra solução é criar um serviço e usá-lo em torno da variável $ http.

 angular.module('App', []) .factory('myHttp',['$http',function($http) { return function(url, success, failure) { $http.get(url).success(function(json) { var data = examineJSONResponse(json); data && data.success ? success() : failure(); }).error(failure); ); } }]); 

E agora isso pode ser chamado assim:

 myHttp(url, onSuccess, onFailure);