AngularJS 捕获 $http 操作的所有状态代码?

AngularJS catch all status-codes for $http actions?

我的$http函数可以return出现以下错误:

POST http://foobar.dev/foobar 500 (Internal Server Error)

POST http://foobar.dev/foobar 401 (Unauthorized)

有没有一种方法可以捕获所有状态代码?

$http.post('/foobar', form)
    .success(function(data, status, headers, config) {
        console.info(data);
    })
    .error(function(data, status, headers, config) {
        console.error(data);
        if(status === 401) {
            $scope.setTemplate('show-login');
        }
        if(status === 500) {
            $scope.setTemplate('server-error');
        }
    }
);  

其中 $scope.setTemplate() 是 Controller 中设置视图的函数。

但是我必须为每个 error() 函数执行此操作并且有很多这样的函数也不会使其成为 DRY 代码 :P

我想要的是捕获错误并根据错误中 returned 的状态代码执行操作。

仅供参考:我没有使用 Angulars $routeProvider()

不如这样:

var routes = {'401':'show-login', '500': 'server-error'}; 
$scope.setTemplate(routes[status]);

其中 routes 是包含您的错误代码和所需路由的字典。

这正是 $http 拦截器的用途。请参阅此处的拦截器部分:$http

基本上,您为所有 $http 请求创建通用功能,您可以在其中处理不同的状态。例如:

// register the interceptor as a service
$provide.factory('myHttpInterceptor', function($q, dependency1, dependency2){
    return {
        response: function(response){
            // do something for particular error codes
            if(response.status === 500){
                // do what you want here
            }
            return response;
        }
    };
});

// add the interceptor to the stack
$httpProvider.interceptors.push('myHttpInterceptor');

您可以使用 Angular $http 拦截器,就像@Dalorzo 解释的那样:

var myApp = angular.module("myApp", [], ['$httpProvider', function($httpProvider) {

    $httpProvider.interceptors.push(['$rootScope', '$q', function($rootScope, $q) {
        return {
            'responseError': function(response) {
                var status = response.status;
                // Skip for response with code 422 (as asked in the comment)
                if (status != 422) {
                    var routes = {'401': 'show-login', '500': 'server-error'};
                    $rootScope.$broadcast("ajaxError", {template: routes[status]});
                }

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

然后在您的控制器中接收它:

$scope.$on("ajaxError", function(e, data) {
    $scope.setTemplate(data.template);
});

现在,您不必输入每个 error 函数。

我最初要说的是为 $http 服务创建一个 decorator 或创建一个服务作为 $http 服务的包装器。