【问题标题】:Handling error in AngularJS when consuming WebApi使用 WebApi 时处理 AngularJS 中的错误
【发布时间】:2015-08-09 13:37:43
【问题描述】:

在下面的代码中,我想处理错误:

  • 401:重定向到登录页面
  • other : 显示错误信息(在错误信息中收到)

我没有找到正确的方法。

有什么想法吗?

谢谢,

模块.js

var app;  
(function () {  
    app = angular.module("studentModule", []);  
})() 

Service.js

app.service('StudentService', function ($http) {    
    this.getAllStudent = function () {  
        return $http.get("http://myserver/api/Student/");  
    }  
});

Controller.js

app.controller('studentController', function ($scope, StudentService) { 

    function GetAllRecords() {  
        var promiseGet = StudentService.getAllStudent();  
        promiseGet.then(function (pl) { $scope.Students = pl.data },  
              function (errorPl) {  
                  $log.error('Some Error in Getting Records.', errorPl);  
              });  
    } 

});

【问题讨论】:

  • 你可以使用http拦截器并在常见的地方进行
  • 是的,拦截器是必经之路。

标签: javascript angularjs asp.net-web-api error-handling


【解决方案1】:

与大多数问题一样,在 AngularJS 中处理来自 AJAX 请求的错误有很多不同的方法。如前所述,最简单的方法是使用 HTTP 拦截器。这可以处理身份验证和错误。

app.config(['$httpProvider', function($httpProvider) {
  $httpProvider.interceptors.push(['$rootScope', '$q', function($rootScope, $q) {

    return {
      responseError: function(rejection) {
        var deferred;

        // If rejection is due to user not being authenticated
        if ( rejection.status === 401 ) {

          $rootScope.$broadcast('unauthenticated', rejection);

          // Return a new promise since this error can be recovered
          // from, like redirecting to login page. The rejection and
          // and promise could potentially be stored to be re-run
          // after user is authenticated.
          deferred = $q.defer();
          return deferred.promise;
        }

        $rootScope.$broadcast('serverError', rejection);
        // Just reject since this probably isn't recoverable from
        return $q.reject(rejection);

      }
    }
  };
}]);

上述拦截器是使用匿名函数创建的,但工厂可用于处理一个或多个不同的拦截器。 AngularJS 文档有关于如何编写不同文档的不错信息:https://docs.angularjs.org/api/ng/service/$http#interceptors

拦截器就位后,您现在只需在 run 方法或任何控制器中监听广播事件。

app.run(['$rootScope', '$location', function($rootScope, $location) {

  $rootScope.$on('unauthenticated', function(response) {
    // Redirect to login page
    $location.path('/login');
  });

  $rootScope.$on('serverError', function(response) {
    // Show alert or something to give feedback to user that
    // server error was encountered and they need to retry
    // or just display this somewhere on the page
    $rootScope.serverError = response.data.errorMessage;
  });
}]);

在你看来:

<body ng-app="studentModule">
  <div id="server_error" ng-if="!!serverError">{{serverError}}</div>
  ...rest of your page
</body>

与几乎所有 AngularJS 代码一样,其中大部分可以抽象为不同的工厂和服务,但这应该是一个很好的起点。

【讨论】:

  • @Kris-I 在定义studentModule 后,所有的JavaScript 都可以粘贴到您的项目中。我在答案中添加了更多内容,包括一些示例 HTML,以帮助您入门,但实际处理身份验证和显示错误可能超出了此问题的范围。
  • 这一切对我来说都很奇怪 :) 我有:
  • 这很好(并且可能是首选),您不需要更改它。只要您在初始化ng-app 的标签内有错误DIV。我将首先在运行块中设置$rootScope.serverError = "Oh, no, something went wrong!";,但在$on 事件处理程序之外,以确保它显示在您的页面上。
  • 我需要服务拦截器吗?通过控制器?
  • 不,我们在配置函数中设置这些的原因是它们可以处理整个应用程序的所有请求。任何使用 $http 进行 HTTP 调用的服务或控制器都会通过我们的拦截器运行任何失败的响应。无需额外的工作。也许花一些时间学习 AngularJS 中的 configrun。陡峭的学习曲线,但一旦点击,你肯定会很有效率。祝你好运!
猜你喜欢
  • 2016-02-07
  • 1970-01-01
  • 2016-03-14
  • 1970-01-01
  • 1970-01-01
  • 2014-06-22
  • 1970-01-01
  • 2014-01-07
  • 1970-01-01
相关资源
最近更新 更多