2013-10-03 38 views
14

Điều này có vẻ như là một yêu cầu lạ. Tôi đã tự hỏi nếu có một cách sử dụng một $ http đánh chặn để bắt URL đầu tiên có một tình trạng phản ứng của 500, sau đó dừng lại tất cả các yêu cầu và quy trình tiếp theo và làm điều gì đó?AngularJS: Bắt tất cả trạng thái phản hồi 500

Trả lời

9

Bạn có thể xem tất cả câu trả lời qua $httpProvider.responseInterceptors.

Để thực hiện điều này, bạn phải tạo một nhà máy như thế này:

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

Trong nhà máy này, bạn sẽ nắm bắt được tình trạng phản ứng nếu nó 500 làm những gì bạn muốn. Sau đó từ chối phản hồi.

Bây giờ bạn cần phải đặt nhà máy trong responseInterceptors của $httProvider trong mô-đun cấu hình của bạn như thế:

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

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

Xin lỗi tôi đã nói rằng tôi biết cách tạo một kẻ đánh chặn, tôi đã tự hỏi liệu có cách nào thực sự "dừng" hàng đợi $ http.pendingRequests trong lần đầu tiên trạng thái 500 gặp phải không. –

+0

Tôi cũng đang tìm một giải pháp để dừng tất cả các yêu cầu tiếp theo khi phát hiện một mã trạng thái nhất định (403 trong trường hợp của tôi). Tôi đã có một thiết bị đánh chặn được thiết lập, nhưng không biết làm thế nào để tiếp tục từ đó. Hãy chia sẻ nếu bạn có một giải pháp cho điều này, cảm ơn. – Mark

2

Bạn có thể tạo ra một dịch vụ và đánh chặn để đối phó với điều này,

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

Nếu bạn muốn cho phép yêu cầu được thực hiện lại sau đó bạn chỉ cần gọi ServerErrorService.clear()

HOẶC

Bạn có thể sử dụng phiên bản sửa đổi của câu trả lời này. Mặc dù tôi không chắc chắn cách thức - nếu bạn muốn - bạn sẽ hủy hành động này và cho phép các yêu cầu tiếp theo.

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

Một điều cần nhớ cho cả các giải pháp này, nếu bạn có bất kỳ máy bay đánh chặn khác sau này mà có một phương pháp responseError xác định hoặc bất kỳ bộ xử lý thiết lập với .catch để xử lý các lời hứa $ http, họ sẽ nhận được một đối tượng phản hồi với {data:null, status:0}

10

Thomas answer là chính xác, nhưng giải pháp này hiện tại là không được dùng nữa. Bạn nên làm một cái gì đó như thế này 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');  
}); 
Các vấn đề liên quan