最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - AngularJS infinite loop when redirecting - Stack Overflow

programmeradmin1浏览0评论

I have an app that does login and has to make decisions on whether or not the user can go to certain pages if they are logged in or not. The issue i'm having is that upon hitting a certain route, I don't need a template, but I call a service to handle sending them to the login page or letting them continue. The service checks to see if they're logged in and if not if uses window.location.href to send them to the login route.

When it hits the window.location.href line, the login controller is infinitely initialized (10 $digest() iterations reached) and nothing works after that point. Am I missing something as far as redirecting goes with hashes?

This only happens in IE9. The looping issue doesn't happen in chrome nor safari.

The routing code:

angular.module('myApp', []).config(['$routeProvider', function($routeProvider) { 
$routeProvider
  .when('/login', {templateUrl: 'partials/login.html', controller: 'LoginCtrl', title:'Login'})
  .when('/register', {template  : " ", controller:  'RegisterCtrl', title:'Register'})
  .when('/eBooks', {resolve: {redirect: 'LoginRouter'}});
}]);

The service for handling login routing:

.service('LoginRouter', ['RouteService', '$rootScope', '$window',  function(RouteService, $rootScope, $window) {        

if (!$rootScope.isLoggedIn) {
    RouteService.setModule("eBooks");
    $window.location.href = "#/login"; // Causing infinite loop
}
else {
    var config = $rootScope.config; 
    $rootScope.startLoading();
    $window.location.href = config.EBOOK_URL+ "&bookId=" + config.bookId.replace("-","");
}
}]);

The login controller:

.controller('LoginCtrl',['$scope' ,'LoginService', function ($scope, LoginService) {
    $scope.user = {mtn: ""};
    $scope.checkUser = function() {
        LoginService.validateUser($scope);
    };
}]); 

NOTE: I changed the code just to point to an html template with an anchor tag and href pointing to "login" and it worked just fine. It's only when I fire location change through window directly that it gets stuck in the loop.

UPDATE: I removed everything from the login.html template to see if something in the html was causing the issue, removed all directives, and any functions/models on the controller scope and rootScope and still the issue happens.

UPDATE 2 I tried using angular to force a click on an anchor to try and bypass the issue but it still happens. A funny thing I noticed is that if I have the console window open in IE then the issue doesn't even happen in the first place. What is going on????

I have an app that does login and has to make decisions on whether or not the user can go to certain pages if they are logged in or not. The issue i'm having is that upon hitting a certain route, I don't need a template, but I call a service to handle sending them to the login page or letting them continue. The service checks to see if they're logged in and if not if uses window.location.href to send them to the login route.

When it hits the window.location.href line, the login controller is infinitely initialized (10 $digest() iterations reached) and nothing works after that point. Am I missing something as far as redirecting goes with hashes?

This only happens in IE9. The looping issue doesn't happen in chrome nor safari.

The routing code:

angular.module('myApp', []).config(['$routeProvider', function($routeProvider) { 
$routeProvider
  .when('/login', {templateUrl: 'partials/login.html', controller: 'LoginCtrl', title:'Login'})
  .when('/register', {template  : " ", controller:  'RegisterCtrl', title:'Register'})
  .when('/eBooks', {resolve: {redirect: 'LoginRouter'}});
}]);

The service for handling login routing:

.service('LoginRouter', ['RouteService', '$rootScope', '$window',  function(RouteService, $rootScope, $window) {        

if (!$rootScope.isLoggedIn) {
    RouteService.setModule("eBooks");
    $window.location.href = "#/login"; // Causing infinite loop
}
else {
    var config = $rootScope.config; 
    $rootScope.startLoading();
    $window.location.href = config.EBOOK_URL+ "&bookId=" + config.bookId.replace("-","");
}
}]);

The login controller:

.controller('LoginCtrl',['$scope' ,'LoginService', function ($scope, LoginService) {
    $scope.user = {mtn: ""};
    $scope.checkUser = function() {
        LoginService.validateUser($scope);
    };
}]); 

NOTE: I changed the code just to point to an html template with an anchor tag and href pointing to "login" and it worked just fine. It's only when I fire location change through window directly that it gets stuck in the loop.

UPDATE: I removed everything from the login.html template to see if something in the html was causing the issue, removed all directives, and any functions/models on the controller scope and rootScope and still the issue happens.

UPDATE 2 I tried using angular to force a click on an anchor to try and bypass the issue but it still happens. A funny thing I noticed is that if I have the console window open in IE then the issue doesn't even happen in the first place. What is going on????

Share Improve this question edited Oct 15, 2013 at 19:04 Jeremy Reed asked Oct 9, 2013 at 15:50 Jeremy ReedJeremy Reed 3191 gold badge7 silver badges20 bronze badges 2
  • Why don't you use window.location.hash instead? That's guaranteed (on IE9 at least) not to reload the page. – Sergiu Paraschiv Commented Oct 9, 2013 at 15:57
  • or $location.path('/login'); – Whisher Commented Oct 9, 2013 at 16:13
Add a ment  | 

3 Answers 3

Reset to default 1

I would suggest to use absolute paths just to make sure some not-so-clever-browsers (IE!) understands your code. Try to add the the origin:

 window.location.href = $window.location.origin + "#/login"; 

On a side note, I think you are doing it right using $window.location.href instead of $location

That's what is remended by the official AngularJS documentation - see here:

Page reload navigation

The $location service allows you to change only the URL; it does not allow you to reload the page. When you need to change the URL and reload the page or navigate to a different page, please use a lower level API, $window.location.href.

It turns out that the issue was actually the console log statements I had all over the app. I ended up menting them all out and everything started working just fine. I guess this would explain why everything worked when I had console open. Got to love IE.

In case someone else runs across this, as I did, another thing to consider is establishing a base URL on the server as well.

For example, my server redirected the root to '/home'. So 'www.mydomain.' would get redirected to 'www.mydomain./home' via my web server routing constraints. This totally screwed up IE9 (while using angular) and caused it to try and hash-bang after '/home' instead of before, which would cause the url to just keep building '/home#!/home#!/home#!/...' and so on and so forth.

Once I relaxed my server side redirect rules to allow for the home page to be either '/' or '/home', IE9 began working again with the hash-bang being put at the root of the site (www.mydomain./#!/home) instead of after '/home'.

Also, don't forget to add an angular route to handle the root URL as well. For example:

$routeProvider.when('/', {templateUrl: '/templates/home.html', controller: 'homeCtrl'})

Hope this helps someone else out there.

发布评论

评论列表(0)

  1. 暂无评论