2013-10-03 16 views
14

Może to wydawać się dziwną prośbą. Zastanawiam się, czy istnieje sposób użycia przechwytywacza $ http do przechwycenia pierwszego adresu URL, który ma status odpowiedzi 500, a następnie zatrzymania wszystkich kolejnych żądań i procesów i zrobienia czegoś?AngularJS: Złap cały status odpowiedzi 500

Odpowiedz

9

Możesz przechwytywać wszystkie odpowiedzi przez $httpProvider.responseInterceptors.

Do tego trzeba zrobić, aby utworzyć fabrykę takiego:

app.factory('SecurityHttpInterceptor', function($q) { 
     return function (promise) { 
      return promise.then(function (response) { 
       return response; 
      }, 
      function (response) { 
       if (response.status === 500) { 
        //DO WHAT YOU WANT 
       } 
       return $q.reject(response); 
      }); 
     }; 
    }); 

W tej fabryce złapiesz status odpowiedzi, czy to 500 rób co chcesz. Następnie odrzuć odpowiedź.

Teraz trzeba postawić zakład w responseInterceptors z $httProvider w module konfiguracyjnym tak:

app.config(function ($routeProvider, $httpProvider) { 
    $routeProvider 
     .when('/', { 
      templateUrl: 'views/home.html', 
      controller: 'HomeCtrl' 
     }) 
     .otherwise({ 
      templateUrl: 'views/404.html' 
     }); 

    $httpProvider.responseInterceptors.push('SecurityHttpInterceptor'); 
}) 
+0

Niestety powinienem powiedzieć wiedziałem, jak zrobić przechwytywania, zastanawiałem się, czy istnieje sposób, aby rzeczywiście „stop” THE $ http.pendingRequests kolejce po raz pierwszy status 500 napotkano. –

+0

Poszukuję również rozwiązania problemu zatrzymania wszystkich kolejnych żądań po wykryciu określonego kodu statusu (w moim przypadku 403). Mam już konfigurację przechwytującą, ale nie wiem, jak kontynuować. Proszę podziel się, jeśli masz rozwiązanie tego, dzięki. – Mark

2

Można by stworzyć serwis i przechwytywania do czynienia z tym,

.factory('ServerErrorService', function() { 

     var _hasError = false 

     return { 
      get hasError() { 
       return _hasError; 
      }, 
      set hasError(value) { 
       _hasError = value; 
       // you could broadcast an event on $rootScope to notify another service that it has to deal with the error 
      }, 
      clear: clear 
     } 

     function clear() { 
      _hasError = false; 
     } 
}) 


.factory('ServerErrorInterceptor', function ($q, ServerErrorService) { 

    var interceptor = { 

     request: function(config) { 

      if(ServerErrorService.hasError) { 
       var q = $q.defer(); 
       q.reject('prevented request'); 
       return q.promise; 
      } 
      return config; 
     }, 

     responseError: function(response) { 

      if(response.status === 500) { 
       ServerErrorService.hasError = true; 
      } 

      return $q.reject(response); 
     } 
    } 

    return interceptor; 
}) 

Jeśli chciałeś zezwolić na ponowienie próśb, musisz tylko zadzwonić pod numer ServerErrorService.clear()

LUB

Możesz użyć zmodyfikowanej wersji tej odpowiedzi. Chociaż nie jestem pewien, w jaki sposób - jeśli chcesz - możesz anulować to działanie i zezwolić na kolejne żądania.

https://stackoverflow.com/a/25475121/1798234

.factory('ServerErrorInterceptor', function ($q) { 
    var canceller = $q.defer(); 
    var interceptor = { 

     request: function(config) { 
      config.timeout = canceller.promise; 
      return config; 
     }, 

     responseError: function(response) { 

      if(response.status === 500) { 
       canceller.resolve('server error'); 
      } 

      return $q.reject(response); 
     } 
    } 

    return interceptor; 
}) 

Jedną rzeczą do zapamiętania dla obu tych rozwiązań, jeśli masz jakiekolwiek inne przechwytujących po tym, że mają responseError metody zdefiniowane lub jakiekolwiek teleskopowe utworzone z .catch przetwarzać obietnicę $ http, otrzymają oni obiekt odpowiedzi z {data:null, status:0}

10

Thomas answer jest poprawne, ale to rozwiązanie jest obecnie przestarzałe. Powinieneś zrobić coś takiego: answer.

app.factory('errorInterceptor', function ($q) { 

    var preventFurtherRequests = false; 

    return { 
     request: function (config) { 

      if (preventFurtherRequests) { 
       return; 
      } 

      return config || $q.when(config); 
     }, 
     requestError: function(request){ 
      return $q.reject(request); 
     }, 
     response: function (response) { 
      return response || $q.when(response); 
     }, 
     responseError: function (response) { 
      if (response && response.status === 401) { 
       // log 
      } 
      if (response && response.status === 500) { 
       preventFurtherRequests = true; 
      } 

      return $q.reject(response); 
     } 
    }; 
}); 

app.config(function ($httpProvider) { 
    $httpProvider.interceptors.push('errorInterceptor');  
}); 
Powiązane problemy