【问题标题】:AngularJS: Catch all response status 500AngularJS:捕获所有响应状态 500
【发布时间】:2013-10-09 14:00:25
【问题描述】:

这似乎是一个奇怪的请求。我想知道是否有办法使用 $http 拦截器来捕获响应状态为 500 的第一个 URL,然后停止所有后续请求和进程并执行某些操作?

【问题讨论】:

    标签: javascript angularjs


    【解决方案1】:

    您可以通过$httpProvider.responseInterceptors获取所有回复。

    为此,您必须像这样创建一个工厂:

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

    在这个工厂中,如果响应状态为 500,则可以按照您的意愿进行操作。然后拒绝响应。

    现在你必须像这样在你的配置模块中将工厂放在$httProviderresponseInterceptors 中:

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

    【讨论】:

    • 对不起,我应该说我知道如何制作拦截器,我想知道是否有办法在第一次遇到状态 500 时真正“停止” $http.pendingRequests 队列。
    • 我还在寻找一种解决方案,以在检测到某个状态码(在我的情况下为 403)时停止所有后续请求。我已经设置了拦截器,但不知道如何从那里继续。如果您有解决此问题的方法,请分享,谢谢。
    【解决方案2】:

    你可以创建一个服务和拦截器来处理这个,

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

    如果您想允许再次发出请求,那么您只需致电ServerErrorService.clear()

    您可以使用此答案的修改版本。虽然我不确定如何 - 如果您愿意 - 您会取消此操作并允许后续请求。

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

    对于这两种解决方案要记住的一点是,如果您在此之后有任何其他拦截器定义了 responseErrormethod 或任何使用 .catch 设置的处理程序来处理 $http 承诺,他们将收到响应带有{data:null, status:0}的对象

    【讨论】:

      【解决方案3】:

      Thomas answer 是正确的,但此解决方案目前已弃用。你应该这样做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');    
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-20
        • 1970-01-01
        • 2018-12-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多