Ich habe einen aktuellen 401-Check, dass ich mit $ location arbeite, was einwandfrei funktioniert. Ich würde es jedoch gerne auf $ state umstellen und stattdessen den ui-router verwenden. Wenn ich dies tue, bekomme ich einen Fehlercode als:
Circular dependency found: $http <- $templateFactory <- $view <- $state <- authHttpResponseInterceptor <- $http <- $compile
Mein momentaner Code sieht gut aus, da ich bestimmte Pfade überprüfe und keinen angemeldeten Benutzern erlauben, sie anzuzeigen:
/* 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');
}]);
Der Code, den ich hinzugefügt habe, lautet wie folgt:
/* 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');
}]);
Warum sollte dieses Problem durch Hinzufügen von Status hervorgerufen werden, wenn es mit dem Standort gut funktioniert?
Es scheint, dass der $ state-Dienst zu einer zirkulären Abhängigkeit mit dem $ http-Dienst führt. Dies kann durch die Tatsache verursacht werden, dass die templateFactory (siehe https://github.com/angular-ui/ui-router/blob/master/src/templateFactory.js ) mit dem $ http-Dienst injiziert wird zusätzlich zum Interceptor selbst mit dem $ http-Service.
Um dieses zyklische Abhängigkeitsproblem zu umgehen, können Sie den $ state-Dienst mit dem $ injector-Dienst an Ihren Interceptor anschließen. Siehe den überarbeiteten Code:
/* 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);
}
};
}]);
Mehr über den $ injector-Service erfahren Sie hier: https://docs.angularjs.org/api/auto/service/ $ injector
Ich würde die Verwendung der Zustandsänderungsereignisse (siehe https://github.com/angular-ui/ui-router/wiki#state-change-events ) empfehlen, um auf Fehler zu achten, die $ stateChangeError verwenden, und den zurückgegebenen Fehler zu überprüfen von der 401.
Hier ist die einfachste Lösung, die ich gemacht habe und es hat funktioniert. In der Fabrik schreiben Sie:
var $http = $injector.get("$http");
und dann $http
wie gewohnt verwenden.
HINWEIS: Wenn in Ihrer Fabrik kein $ Injektor verfügbar ist, spritzen Sie ihn einfach wie folgt ein
.factory('authHttpResponseInterceptor',['$q','$location','$injector', function($q,$location,$injector) {
}])