我有一个当前的401检查我正在使用$ location运行正常。但是我想将它交换到$ state并使用ui-router代替。当我这样做时,我得到一个错误代码:
Circular dependency found: $http <- $templateFactory <- $view <- $state <- authHttpResponseInterceptor <- $http <- $compile
我当前的代码看起来很好,因为我检查了某些路径并且不允许登录用户查看它们:
/* Look for 401 auth errors and then redirect */
.factory('authHttpResponseInterceptor',['$q','$location', function($q,$location) {
return {
response: function(response){
if (response.status === 401) {
}
return response || $q.when(response);
},
responseError: function(rejection) {
var reservedPaths = ['/','/login','/connect','/event'];
if (rejection.status === 401 && _.contains(reservedPaths,$location.path().trim())) {
$location.path('/welcome');
}
return $q.reject(rejection);
}
};
}])
.config(['$httpProvider',function($httpProvider) {
//Http Intercpetor to check auth failures for xhr requests
$httpProvider.interceptors.push('authHttpResponseInterceptor');
}]);
我添加的代码如下:
/* Look for 401 auth errors and then redirect */
.factory('authHttpResponseInterceptor',['$q','$location', **'$state',** function($q,$location, **$state**) {
return {
response: function(response){
if (response.status === 401) {
}
return response || $q.when(response);
},
responseError: function(rejection) {
var reservedPaths = ['/','/mycube','/connect','/event'];
if (rejection.status === 401 && _.contains(reservedPaths,$location.path().trim())) {
**$state.go('home');**
}
return $q.reject(rejection);
}
};
}])
.config(['$httpProvider',function($httpProvider) {
//Http Intercpetor to check auth failures for xhr requests
$httpProvider.interceptors.push('authHttpResponseInterceptor');
}]);
为什么添加状态会在位置正常时导致此问题?
答案 0 :(得分:76)
似乎$ state服务导致与$ http服务的循环依赖。这可能是因为除了拦截器本身由$ http服务组成之外,templateFactory(请参阅https://github.com/angular-ui/ui-router/blob/master/src/templateFactory.js)正在注入$ http服务。
要解决此循环依赖性问题,可以使用$ injector服务将$ state服务连接到拦截器。请参阅修订后的代码:
/* Look for 401 auth errors and then redirect */
module.factory('authHttpResponseInterceptor', ['$q','$location', '$injector', function($q, $location, $injector) {
return {
response: function(response){
if (response.status === 401) {
}
return response || $q.when(response);
},
responseError: function(rejection) {
var reservedPaths = ['/', '/mycube', '/connect', '/event'];
if (rejection.status === 401 && _.contains(reservedPaths, $location.path().trim())) {
var stateService = $injector.get('$state');
stateService.go('home');
}
return $q.reject(rejection);
}
};
}]);
您可以在此处了解有关$ injector服务的更多信息:https://docs.angularjs.org/api/auto/service/ $ injector
我建议使用状态更改事件(请参阅https://github.com/angular-ui/ui-router/wiki#state-change-events)使用$ stateChangeError查看错误并检查401返回的错误。
答案 1 :(得分:1)
这是我做过的最简单的解决方案。在工厂内写道:
var $http = $injector.get("$http");
然后像往常一样使用$http
。
注意:如果您的工厂没有可用的注射器,只需按照以下方式注入
.factory('authHttpResponseInterceptor',['$q','$location','$injector', function($q,$location,$injector) {
}])