【问题标题】:AngularJS catch all status-codes for $http actions?AngularJS 捕获 $http 动作的所有状态码?
【发布时间】:2015-12-03 18:03:35
【问题描述】:

我的$http 函数可能会返回以下错误:

POST http://foobar.dev/foobar 500(内部服务器错误)

POST http://foobar.dev/foobar401(未经授权)

有没有办法可以捕获所有状态码?

$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

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

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

【问题讨论】:

    标签: javascript angularjs angular-http


    【解决方案1】:

    您可以使用 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 函数。

    【讨论】:

    • 这看起来很棒!除了.$on("ajaxError 的数据始终未定义
    • 抱歉。我的错。该函数的第一个参数是事件。我已经更新了答案,请检查一下。让我知道这是否行不通。我试试看。
    • 有效!现在有一个问题;它现在总是拒绝一个错误。我有一些我处理不同的 422 响应。所以我尝试了这个:``` 'responseError': function(response) { if(response.status == 422) { return response; } // 然后是你的代码,但这不是修复。 ```
    【解决方案2】:

    不如这样:

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

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

    【讨论】:

    • 不,不会使其成为 DRY 代码。然后我仍然需要将该行添加到每个错误函数中。
    • 请解释您在回答时遇到的问题,而不是投反对票,因为我认为根据您的需要,答案是最好的。
    • @user1469734 怎么可能比这更简单。如果你知道如何请分享它
    【解决方案3】:

    这正是$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');
    

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-10-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-18
        • 2022-06-23
        • 2015-01-12
        • 1970-01-01
        相关资源
        最近更新 更多