最近,当我在我的应用中实施身份验证时,我遇到了$stateChangeStart
事件的问题。我限制访问某些具有布尔值的页面,如下所示:
.state('login', {
url:'/login',
templateUrl: 'modules/authentication/views/login.html',
controller: 'LoginController',
data: {
requireAuthentication: false
}
})
我想检查,如果有任何身份验证数据,并且用户访问requireAuthentication: true
的路由,他会自动重定向到登录页面。所以,这是一种标准的身份验证行为。
在实施过程中,我遇到Maximum call stack size exceeded
错误。我花了四个晚上才发现那些~10行代码出了什么问题。
我将为我的工作解决方案发布一个答案,那些人可能会照看一个有效的解决方案(就像我一样)。我认为这对其他成员来说是重要的。
答案 0 :(得分:2)
所以,有适合我的工作解决方案:
angular.module('YourModule', [...dependecies...])
.run(function($rootScope, $cookies, $state) {
$rootScope.$on("$stateChangeStart", function(event, toState, toParams, fromState, fromParams) {
var shouldLogin = toState.data.requireAuthentication !== undefined
&& toState.data.requireAuthentication;
// NOT authenticated - wants any private stuff
if(shouldLogin || fromState.name === "") {
var token = $cookies.get('JWT') == null ? null : $cookies.get('JWT');
if (token == null) {
if(toState.name === 'login')
return;
$state.go('login');
event.preventDefault();
} else {
if(toState.name === toState.name)
return;
//TODO: Check token
$state.go(toState.name);
event.preventDefault();
}
}
});
});

所以,我从$cookies
获取身份验证数据。如果它们是null
,我会重定向到login
州。
最重要的部分是:
fromState.name === ""
首次打开页面时,此表达式会使事件处理程序触发
if(toState.name === toState.name)
return;
和
if(toState.name === 'login')
return;
两个if表达式看起来真的很糟糕,但它们可以解决问题。你不会让任何堆栈大小超过异常。
我在Firefox,Chrome,Opera,Mozilla和Yandex浏览器中测试了上述代码,所以我希望它对你有用。