javascript AngularJS:捕获所有响应状态 500

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19149572/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 14:33:47  来源:igfitidea点击:

AngularJS: Catch all response status 500

javascriptangularjs

提问by Ben Kilah

This may seem like a strange request. I was wondering if there is a way using a $http interceptor to catch the first URL that has a response status of 500, then stop all subsequent requests and processes and do something?

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

回答by Zanon

Thomas answeris correct, but this solution is currently deprecated. You should do something like this answer.

Thomas 的回答是正确的,但此解决方案目前已弃用。你应该做类似这个答案的事情。

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

回答by Thomas Pons

You can catch all responses through $httpProvider.responseInterceptors.

您可以通过 捕获所有响应$httpProvider.responseInterceptors

To do this you have to create a factory like this:

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

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

In this factory you'll catch the response status if it's 500 do what you want. Then reject the response.

在这个工厂中,如果它是 500 做你想做的,你会捕捉到响应状态。然后拒绝回复。

Now you have to put the factory in the responseInterceptorsof $httProviderin your config module like that :

现在,你必须把工厂中responseInterceptors$httProvider你的配置模块,就像在:

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

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

回答by james

You could create a service and interceptor to deal with this,

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

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

If you wanted to allow requests to be made again then you just need to call ServerErrorService.clear()

如果你想允许再次提出请求,那么你只需要调用 ServerErrorService.clear()

OR

或者

You could use a modified version of this answer. Although i'm not sure how - if you wanted to - you'd cancel this action and allow subsequent requests.

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

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

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

One thing to remember for both of these solutions, if you have any other interceptors after this that have a responseErrormethod defined or any handlers set up with .catchto process the $http promise, they will receive a response object with {data:null, status:0}

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