未经授权响应的AngularJS(1.1.5)无限循环
Posted
技术标签:
【中文标题】未经授权响应的AngularJS(1.1.5)无限循环【英文标题】:AngularJS(1.1.5) infinite loop on not authorized response 【发布时间】:2013-06-07 22:18:36 【问题描述】:所以,我有一个使用 Angular 编写的应用程序。它本质上是一个 SPA,除了我的登录是通过传统的非 ajax 请求完成的。我想要的只是在服务器返回 401 时将页面(完全绕过路由)重定向到 /logout。我可以设置基于 ajax 的登录,但坦率地说,我没有看到好处。考虑到这一点,如果这样做更容易——我会做任何能让我克服这个非常烦人的障碍的事情,这对于 jQuery 来说非常简单。这是我在删除授权 cookie 时陷入无限循环的原因:
var manageModule = angular.module('manageModule', ['ngResource']);
manageModule.config(function($httpProvider, $routeProvider, $locationProvider)
$httpProvider.defaults.headers.put['Content-Type'] =
'application/x-www-form-urlencoded';
$httpProvider.defaults.headers.post['Content-Type'] =
'application/x-www-form-urlencoded';
$locationProvider.html5Mode(false);
$httpProvider.interceptors.push(function($q, $window)
return
'responseError': function(rejection)
var status = rejection.status;
if (status == 401)
console.log('401 inside if');
$window.location.href = contextPath + '/logout';
return $q.reject(rejection);
);
$routeProvider
.when('/majors',
templateUrl: contextPath+'/manage/majors',
controller: ManageMajorsController
)
.when('/users',
templateUrl: contextPath+'/manage/users',
controller: ManageUsersController
)
.when('/courses',
templateUrl: contextPath+'/manage/courses',
controller: ManageCoursesController
)
.when('/notes',
templateUrl: contextPath+'/manage/notes',
controller: ManageNotesController
)
.when('/manage',
templateUrl: contextPath+'/manage/majors',
controller: ManageMajorsController
);
);
感谢您提供的任何帮助!
这似乎是一种新行为,我记得它处于重定向循环中。无论哪种方式,这都是无限输出到控制台的内容。
Error: 10 $digest() iterations reached. Aborting!
Watchers fired in the last 5 iterations: [["fn: function ()var a=d.url(),b=f.$$replace;if(!m||a!=f.absUrl())m++,\nc.$evalAsync(function()c.$broadcast(\"$locationChangeStart\",f.absUrl(),a).defaultPrevented?f.$$parse(a):(d.url(f.absUrl(),b),i(a)));f.$$replace=!1;return m; newVal: 15; oldVal: 14"],["fn: function ()var a=d.url(),b=f.$$replace;if(!m||a!=f.absUrl())m++,\nc.$evalAsync(function()c.$broadcast(\"$locationChangeStart\",f.absUrl(),a).defaultPrevented?f.$$parse(a):(d.url(f.absUrl(),b),i(a)));f.$$replace=!1;return m; newVal: 16; oldVal: 15"],["fn: function ()var a=d.url(),b=f.$$replace;if(!m||a!=f.absUrl())m++,\nc.$evalAsync(function()c.$broadcast(\"$locationChangeStart\",f.absUrl(),a).defaultPrevented?f.$$parse(a):(d.url(f.absUrl(),b),i(a)));f.$$replace=!1;return m; newVal: 17; oldVal: 16"],["fn: function ()var a=d.url(),b=f.$$replace;if(!m||a!=f.absUrl())m++,\nc.$evalAsync(function()c.$broadcast(\"$locationChangeStart\",f.absUrl(),a).defaultPrevented?f.$$parse(a):(d.url(f.absUrl(),b),i(a)));f.$$replace=!1;return m; newVal: 18; oldVal: 17"],["fn: function ()var a=d.url(),b=f.$$replace;if(!m||a!=f.absUrl())m++,\nc.$evalAsync(function()c.$broadcast(\"$locationChangeStart\",f.absUrl(),a).defaultPrevented?f.$$parse(a):(d.url(f.absUrl(),b),i(a)));f.$$replace=!1;return m; newVal: 19; oldVal: 18"]]
at Error (<anonymous>)
at Object.e.$digest (http://localhost:8080/MetroCredit/static/bundle-main_defer.js:91:135)
at Object.e.$apply (http://localhost:8080/MetroCredit/static/bundle-main_defer.js:92:431)
at j (http://localhost:8080/MetroCredit/static/bundle-main_defer.js:101:80)
at r (http://localhost:8080/MetroCredit/static/bundle-main_defer.js:104:449)
at XMLHttpRequest.v.onreadystatechange (http://localhost:8080/MetroCredit/static/bundle-main_defer.js:106:90) bundle-main_defer.js:63
Uncaught Error: 10 $digest() iterations reached.
【问题讨论】:
当你说无限循环时,你是指角度摘要循环限制还是它实际上在某个地方永远循环。如果它在循环,你在控制台中看到什么吗(例如:'401 inside if')?当您尝试在浏览器中暂停 javascript 执行时会发生什么?循环在哪里?是重定向循环吗? 我注释掉了我的 http 拦截器代码,实际上发生了同样的事情。 太棒了。其实我以前看过这个:) 这里也一样! :-( 而且它并不总是发生,只会发生几次。很奇怪!你找到解决方案了吗? 同样的事情发生在我身上,似乎 spring security 在 url 的末尾添加了 hash,angular 试图删除它但 chrome 再次返回它,这会导致循环。 【参考方案1】:可能和这个issue有关。
当我根本不想使用 Angular 的路由时,我以前在控制器中使用过这个:
// Abort Angular JS default location change handling.
$scope.$on('$locationChangeStart', function(event, newUrl, oldUrl)
if (newUrl == $location.absUrl())
event.preventDefault();
);
对于您的情况,您似乎只想摆脱某些 URL,因此您可能希望/需要做一些模式匹配来代替 newUrl == $location.absUrl()
。
这可能不适合您,因为我想避免使用 Angular 的所有路由机制,而且我不确定它与新版本的兼容性如何。我在 Angular 1.0.x 版本中使用过它。
【讨论】:
我在 1.1.5 上,然后我切换到 1.0.7,我不再得到那个无限循环。 我发布的内容应该杀死所有路由,这就是为什么我说您需要将其更改为仅在某些条件下调用event.preventDefault()
。以上是关于未经授权响应的AngularJS(1.1.5)无限循环的主要内容,如果未能解决你的问题,请参考以下文章
使用 Cordova 和 Angularjs 登录 Twitter:401 未经授权的错误