发现循环依赖:Http Response Interceptor 401
Circular dependency found: Http Response Interceptor 401
基本思路是使用 Http 响应拦截器在我的网页显示 401 状态时重定向它。但我不知道我是否以正确的方式这样做:我认为它是这样的,但我似乎比看起来更难。目前我找到了一个循环依赖项。
我需要将拦截器推到别处吗?拦截器如何知道我是否收到 401 请求。是否也可以定义哪些 401 需要拦截,哪些忽略
(function () {
'use strict';
angular
.module('app', ['ngRoute','ngCookies','ngMessages'])
.config(routeConfig);
routeConfig.$inject = ['$routeProvider','$httpProvider'];
function routeConfig($routeProvider,$httpProvider) {
$routeProvider
.when('/', {
templateUrl: 'login.html',
controller : 'LoginController'
})
.when('/register', {
templateUrl: 'register.html',
controller : 'RegisterController'
})
.when('/main', {
//This gives an 401 status when the user has not been logged in
templateUrl: 'home.html',
controller : 'HomeController'
})
.otherwise('/');
// We need to add this for csrf protection
$httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
//this gives an Circular dependency error
$httpProvider.interceptors.push('HttpResponseInterceptor');
}
})();
这是我的服务:
(function () {
'use strict';
angular
.module('app')
.factory('HttpResponseInterceptor', HttpResponseInterceptor);
HttpResponseInterceptor.$inject = ['$rootScope','$http','$q','$location'];
function HttpResponseInterceptor($rootScope,$http,$q,$location) {
return {
response: function(response){
if (response.status === 401) {
}
return response || $q.when(response);
},
responseError: function(rejection) {
if (rejection.status === 401) {
$location.path('/login');
}
return $q.reject(rejection);
}
};
}
})();
更新2
正如评论中提到的,我注入了很多东西。所以这是一个已解决的问题,但是现在当我进入登录页面时,它会发出加载页面的请求(本地主机:8080/用户),这会导致无限循环重定向到登录页面并导致浏览器崩溃.
那么有什么方法可以告诉拦截器哪些url需要重定向,哪些不需要
使用 $injector 注入服务有帮助吗?
(function () {
'use strict';
angular
.module('admin')
.factory('HttpInterceptor', httpInterceptor);
httpInterceptor.$inject = [
'$q', // return promises
'$injector' // login service injection
];
function httpInterceptor(q, injector) {
return {
responseError: function (rejection) {
var url = rejection.config ? rejection.config.url : undefined;
var state = injector.get("$state");
if (rejection.status === 401) {
if (!(url === "/api/logout" || state.current.name === "login" && url === "/api/authenticated")) {
var loginService = injector.get('LoginService');
loginService.logout();
}
}
if (rejection.status === 403) {
state.go("home");
}
return q.reject(rejection);
}
};
}
}());
这是第二个问题的答案...
您查询拒绝对象并向您的 IF 语句添加一些进一步的条件...
您可以使用...转储拒绝对象
console.log(JSON.stringify(拒绝));
然后将条件添加到您的 IF ...
if (rejection.status === 401 && rejection.config.url !== "/url/you/do/not/want/to/change/state/on") {
// do state.go or something else here
}
基本思路是使用 Http 响应拦截器在我的网页显示 401 状态时重定向它。但我不知道我是否以正确的方式这样做:我认为它是这样的,但我似乎比看起来更难。目前我找到了一个循环依赖项。
我需要将拦截器推到别处吗?拦截器如何知道我是否收到 401 请求。是否也可以定义哪些 401 需要拦截,哪些忽略
(function () {
'use strict';
angular
.module('app', ['ngRoute','ngCookies','ngMessages'])
.config(routeConfig);
routeConfig.$inject = ['$routeProvider','$httpProvider'];
function routeConfig($routeProvider,$httpProvider) {
$routeProvider
.when('/', {
templateUrl: 'login.html',
controller : 'LoginController'
})
.when('/register', {
templateUrl: 'register.html',
controller : 'RegisterController'
})
.when('/main', {
//This gives an 401 status when the user has not been logged in
templateUrl: 'home.html',
controller : 'HomeController'
})
.otherwise('/');
// We need to add this for csrf protection
$httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
//this gives an Circular dependency error
$httpProvider.interceptors.push('HttpResponseInterceptor');
}
})();
这是我的服务:
(function () {
'use strict';
angular
.module('app')
.factory('HttpResponseInterceptor', HttpResponseInterceptor);
HttpResponseInterceptor.$inject = ['$rootScope','$http','$q','$location'];
function HttpResponseInterceptor($rootScope,$http,$q,$location) {
return {
response: function(response){
if (response.status === 401) {
}
return response || $q.when(response);
},
responseError: function(rejection) {
if (rejection.status === 401) {
$location.path('/login');
}
return $q.reject(rejection);
}
};
}
})();
更新2
正如评论中提到的,我注入了很多东西。所以这是一个已解决的问题,但是现在当我进入登录页面时,它会发出加载页面的请求(本地主机:8080/用户),这会导致无限循环重定向到登录页面并导致浏览器崩溃.
那么有什么方法可以告诉拦截器哪些url需要重定向,哪些不需要
使用 $injector 注入服务有帮助吗?
(function () {
'use strict';
angular
.module('admin')
.factory('HttpInterceptor', httpInterceptor);
httpInterceptor.$inject = [
'$q', // return promises
'$injector' // login service injection
];
function httpInterceptor(q, injector) {
return {
responseError: function (rejection) {
var url = rejection.config ? rejection.config.url : undefined;
var state = injector.get("$state");
if (rejection.status === 401) {
if (!(url === "/api/logout" || state.current.name === "login" && url === "/api/authenticated")) {
var loginService = injector.get('LoginService');
loginService.logout();
}
}
if (rejection.status === 403) {
state.go("home");
}
return q.reject(rejection);
}
};
}
}());
这是第二个问题的答案...
您查询拒绝对象并向您的 IF 语句添加一些进一步的条件...
您可以使用...转储拒绝对象
console.log(JSON.stringify(拒绝));
然后将条件添加到您的 IF ...
if (rejection.status === 401 && rejection.config.url !== "/url/you/do/not/want/to/change/state/on") {
// do state.go or something else here
}