我试图在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请求,所以我可以从数据库中检索用户信息。
请注意:我知道有很多不同的,也许是更好的方法来实现某种身份验证方法,比如在标头中使用令牌。我已经意识到这一点,并且 正在寻找有关不同的,更好的身份验证方法的答案。我想对这个具体问题有答案。
答案 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
时,拦截器本身才应该执行请求(这意味着请求没有来自拦截器内部) - 避免无限循环!