AngularJS使用拦截器处理$http 404错误 - 承诺未定义错误

19

我有一个Angular应用程序,希望从API端点处理404错误。关键组件如下:

// app.js

var myApp = angular.module('myApp', ['ngRoute',]);

myApp.config( function ($httpProvider, $interpolateProvider, $routeProvider) {
  $httpProvider.interceptors.push('httpRequestInterceptor');

  $routeProvider
    ...
    .when('/project/:projectId', {
        templateUrl : 'partials/project_detail.tmpl.html',
        controller: 'ProjectDetailCtrl',
        resolve: {
            project: function ($route, ConcernService) {
                return ConcernService.get('projects/', $route.current.params.projectId);
            },
        }
    });
});


// interceptors.js

myApp.factory('httpRequestInterceptor', function ($q, $location) {
  return {
    response: function(response){
      return promise.then(
        function success(response) {
          return response;
        },
        function error(response) {
          if(response.status === 404){
            $location.path('/404');
            return $q.reject(response);
          }
          else{
            return $q.reject(response); 
          }
        }
      );
    }
  };
});


// services.js

myApp.factory('ConcernService', function ($http, $q) {

var ConcernService = {
    ...
    get: function (items_url, objId) {
        var defer = $q.defer();
        $http({method: 'GET', 
            url: api_url + items_url + objId}).
            success(function (data, status, headers, config) {
                defer.resolve(data);
            }).error(function (data, status, headers, config) {
                // when API not found, status == 404 
                console.log('ConcernService.get status',status);
                defer.reject(status);
            });
        console.log('ConcernService.get promise',defer.promise);
        return defer.promise;
    },
}
});

我的问题是我在响应中遇到了一个错误,ReferenceError: promise is not defined at response。这是因为ConcernService延迟了promise吗?我该如何解决这个问题?


你正在使用哪个版本的Angular? - Ajay Beniwal
Angular 版本 1.2.9 - Darwin Tech
1
看起来你正在混合使用拦截器和响应拦截器(已弃用)。你收到的错误在 return promise.then(... 那里,promise 在那里没有定义。http://docs.angularjs.org/api/ng/service/$http - Anthony Chu
您正在使用已弃用的定义,请参考新语法。 - Ajay Beniwal
你能否给我一些使用新的 inceptor 语法的示例? - Darwin Tech
没有拦截器可能吗? - Bhumi Singhal
3个回答

37

所以,我的解决方案使用新的interceptor语法,并按照以下方式工作:

// interceptors.js

.factory('httpRequestInterceptor', function ($q, $location) {
    return {
        'responseError': function(rejection) {
            // do something on error
            if(rejection.status === 404){
                $location.path('/404/');                    
            }
            return $q.reject(rejection);
         }
     };
});


// app.js

myApp.config( function ($httpProvider, $interpolateProvider, $routeProvider) {
    $httpProvider.interceptors.push('httpRequestInterceptor');

    $routeProvider
    ...
    .when('/404/:projectId', {
        templateUrl : 'partials/404.tmpl.html',
        controller: '404Ctrl',
        resolve: {
            project: function ($route) {
                // return a dummy project, with only id populated
                return {id: $route.current.params.projectId};
            }
        }
    });
});


// 404.tmpl.html

...

<h1>Oh No! 404.</h1> 
<p>Project with ID {{ project.id }} does not exist.</p>

这只是一个简化版本,但演示了我如何使用拦截器模式来解决我的问题。

欢迎留下评论。


1
拦截器工厂中的$location.path是否会实际更新位置?这对我没有起作用。我发现必须使用'$window.location.href=...'。 - ericpeters0n
1
这个答案有一个关键问题。返回语句"return $q.reject(rejection);"应该在IF块之外,否则它会破坏拦截器链。 - Amit

2

е®һйҷ…дёҠпјҢжҲ‘д»ҺиҝҷйҮҢжҸҗеҸ–дәҶinterceptorд»Јз Ғпјҡhttp://djds4rce.wordpress.com/2013/08/13/understanding-angular-http-interceptors/ еҸӘжҳҜе°Ҷ401жӣҙж”№дёә404гҖӮ - Darwin Tech
在你的例子中,interceptor 提供了部分内容和 Controller。我更倾向于在应用程序配置中使用 ngRoute 来处理 /404 - Darwin Tech
是的,当我们收到400错误时,我们会弹出一个警报对话框,因此需要使用部分和控制器。显然,在路由上处理404会有所不同。 - MBielski

0

将参数作为传递更容易

<div class="fullPortfolio" ng-show="projectId.length">已传递项目ID</div>

当项目ID不存在时

<div class="fullPortfolio" ng-show="!projectId.length">项目ID不存在</div>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接