AngularJS: получить весь статус ответа 500

Это может показаться странным запросом. Мне было интересно, есть ли способ использовать перехватчик $http, чтобы поймать первый URL-адрес, имеющий статус ответа 500, а затем остановить все последующие запросы и процессы и что-то сделать?

Ответы

Ответ 1

Ответ Томаса правильный, но это решение в настоящее время устарело. Вы должны сделать что-то вроде .

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

Ответ 2

Вы можете получить все ответы через $httpProvider.responseInterceptors.

Для этого вам нужно создать factory следующим образом:

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

В этом factory вы поймаете статус ответа, если он сделает то, что вы хотите. Затем отклоните ответ.

Теперь вы должны поместить factory в responseInterceptors of $httProvider в свой конфигурационный модуль следующим образом:

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

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

Ответ 3

Вы можете создать службу и перехватчик, чтобы справиться с этим,

.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()

ИЛИ

Вы можете использовать модифицированную версию этого ответа. Хотя я не уверен, как - если бы вы захотели - вы отмените это действие и разрешите последующие запросы.

fooobar.com/info/379195/...

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

Одна вещь, которую следует помнить для обоих этих решений, если после этого у вас есть другие перехватчики, которые имеют метод responseError или любые обработчики, настроенные с помощью .catch для обработки обещания $http, они получат ответ объект с {data:null, status:0}