在拦截器中执行Ajax请求

时间:2014-08-21 08:13:50

标签: angularjs angular-resource angular-http-interceptors

我试图在AngularJS中创建一个拦截器来检查我是否已经登录。它是通过查看$rootScope.user变量来实现的。

如果$rootScope.user变量不存在,那么我想进行一次Ajax调用,看看服务器上是否还有一个Session活动。

问题是我最终陷入无限循环,因为我的拦截器拦截了我所有的Ajax请求......

我现在基本上有这个:

.factory('resourceInterceptor', ['$rootScope', 'AccountService', function($rootScope, accountService) {
    return {
        request: function(request) {
            if(!$rootScope.user) {
                var userData = accountService.getUserSession(); // creates loop
                //var userData = $http.get('api/Account'); // Same thing
            }

            return request;
        }
    }
}]);

但是这不起作用,它会出现这个错误:

Error: [$injector:cdep] Circular dependency found: $http <- $resource <- AccountService <- resourceInterceptor <- $http <- $compile

或与$ http:

相同
Error: [$injector:cdep] Circular dependency found: $http <- resourceInterceptor <- $http <- $compile

那我怎么能解决这个问题呢?我想从我的拦截器做一个Ajax请求,所以我可以从数据库中检索用户信息。


请注意:我知道有很多不同的,也许是更好的方法来实现某种身份验证方法,比如在标头中使用令牌。我已经意识到这一点,并且 正在寻找有关不同的,更好的身份验证方法的答案。我想对这个具体问题有答案。

2 个答案:

答案 0 :(得分:0)

您必须使用$ injector服务并使用其功能获取$ http服务。

它看起来像这样(带有$ http的例子):

.factory('resourceInterceptor', ['$rootScope', '$injector', '$q', function($rootScope, $injector, $q) {

    return {
        request: function(config) {

            var $http = $injector.get('$http');

            if(!$rootScope.user) {
                var userData = $http.get('api/Account');
            }

            return config || $q.when(config);
        }
    }
}]);

这是在拦截器中使用$ http的情况下已知的循环依赖问题(每个都依赖于彼此)。


示例plunkr - http://plnkr.co/edit/7zEuVlHgGNyBbzCg8Lfi?p=preview

关于官方AngularJS github存储库的问题和答案 - link

有关来自官方AngularJS文档的$ injector的信息 - link

有关egghead.io上的$ injector的信息 - link

答案 1 :(得分:0)

here描述的技术可能对您有所帮助。在您在拦截器内部进行的请求中,您将设置自定义属性(bypassErrorsInterceptor),并且只有在未设置bypassErrorsInterceptor时,拦截器本身才应该执行请求(这意味着请求没有来自拦截器内部) - 避免无限循环!

相关问题