$ http 인터셉터에 $ state (ui-router)를 주입하면 순환 종속성이 발생합니다.
내가 달성하려고하는 것
$ http 요청이 401 오류를 반환하는 경우 특정 상태 (로그인)로 전환하고 싶습니다. 따라서 $ http 인터셉터를 만들었습니다.
문제
'$ state'를 인터셉터에 삽입하려고하면 순환 종속성이 발생합니다. 왜 그리고 어떻게 수정합니까?
암호
//Inside Config function
var interceptor = ['$location', '$q', '$state', function($location, $q, $state) {
function success(response) {
return response;
}
function error(response) {
if(response.status === 401) {
$state.transitionTo('public.login');
return $q.reject(response);
}
else {
return $q.reject(response);
}
}
return function(promise) {
return promise.then(success, error);
}
}];
$httpProvider.responseInterceptors.push(interceptor);
수정
$injector서비스를 사용하여 서비스에 대한 참조를 얻으십시오 $state.
var interceptor = ['$location', '$q', '$injector', function($location, $q, $injector) {
function success(response) {
return response;
}
function error(response) {
if(response.status === 401) {
$injector.get('$state').transitionTo('public.login');
return $q.reject(response);
}
else {
return $q.reject(response);
}
}
return function(promise) {
return promise.then(success, error);
}
}];
$httpProvider.responseInterceptors.push(interceptor);
원인
angular-ui-router 는 $http서비스를 종속성으로 삽입 $TemplateFactory한 다음 인터셉터를 디스패치 할 $http때 $httpProvider자체 내에 순환 참조를 작성합니다 .
The same circular dependency exception would be thrown if you attempt to inject the $http service directly into an interceptor like so.
var interceptor = ['$location', '$q', '$http', function($location, $q, $http) {
Separation of Concerns
Circular dependency exceptions can indicate that there is a mixing of concerns within your application which could cause stability issues. If you find yourself with this exception you should take the time to look at your architecture to ensure you avoid any dependencies that end up referencing themselves.
@Stephen Friedrich's answer
I agree with the answer below that using the $injector to directly get a reference to the desired service is not ideal and could be considered an anti pattern.
Emitting an event is a much more elegant and also decoupled solution.
The question is a duplicate of AngularJS: Injecting service into a HTTP interceptor (Circular dependency)
I am re-posting my answer from that thread here:
A Better Fix
I think using the $injector directly is an antipattern.
A way to break the circular dependency is to use an event: Instead of injecting $state, inject $rootScope. Instead of redirecting directly, do
this.$rootScope.$emit("unauthorized");
plus
angular
.module('foo')
.run(function($rootScope, $state) {
$rootScope.$on('unauthorized', () => {
$state.transitionTo('login');
});
});
That way you have separated the concerns:
- Detect a 401 response
- Redirect to login
Jonathan's solution was great until I tried to save the current state. In ui-router v0.2.10 the current state does not seem to be populated on initial page load in the interceptor.
Anyway, I solved it by using the $stateChangeError event instead. The $stateChangeError event gives you both to and from states, as well as the error. It's pretty nifty.
$rootScope.$on('$stateChangeError',
function(event, toState, toParams, fromState, fromParams, error){
console.log('stateChangeError');
console.log(toState, toParams, fromState, fromParams, error);
if(error.status == 401){
console.log("401 detected. Redirecting...");
authService.deniedState = toState.name;
$state.go("login");
}
});
'IT story' 카테고리의 다른 글
| Matlab에서 함수 매개 변수의 기본값을 어떻게 설정합니까? (0) | 2020.07.17 |
|---|---|
| JSONObject를 사용하여 Java에서 올바른 JSONArray를 작성하는 방법 (0) | 2020.07.17 |
| memcached에 모든 키를 설정하십시오. (0) | 2020.07.17 |
| 'id'는 파이썬에서 잘못된 변수 이름입니다. (0) | 2020.07.17 |
| Maven 종속성을 사용하도록 Eclipse 빌드 경로를 구성하는 방법은 무엇입니까? (0) | 2020.07.17 |