You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AngularJS路由$routeChangeSuccess未广播,需实现路由权限校验与403跳转

AngularJS ngComponentRouter 权限校验与重定向方案

哦,我懂你的问题了——你肯定是把旧的ngRoute模块的事件和ngComponentRouter搞混了!$routeChangeSuccess是ngRoute专属的广播事件,而你用的是AngularJS 1.5+推出的组件路由(ngComponentRouter),这俩根本不是一套东西,所以你监听不到这个事件太正常了😅。

下面给你两种适合ngComponentRouter的权限校验方案,都是官方推荐的方式:

方案一:组件内用$routerOnActivate钩子(推荐)

组件路由的设计就是和组件生命周期深度绑定的,每个路由对应的组件都可以实现$routerOnActivate钩子,这个钩子会在路由激活之前触发,正好用来做权限校验:

angular.module('yourApp').component('protectedDashboard', {
  template: '<h2>仅授权用户可见的仪表盘</h2>',
  controller: function($router, AuthService) {
    // 路由激活前的钩子
    this.$routerOnActivate = function(nextRoute, prevRoute) {
      // 这里替换成你的权限校验逻辑,比如检查用户角色、路由权限
      const hasAccess = AuthService.checkUserAccess(nextRoute.routeConfig.path);
      
      if (!hasAccess) {
        // 重定向到403页面(假设你的403路由名称是Forbidden)
        $router.navigate(['Forbidden']);
      }
    };
  }
});
  • nextRoute参数里包含了目标路由的所有配置信息,比如nextRoute.routeName、nextRoute.routeConfig,可以用来精准判断权限。
  • 这个方案适合需要针对单个组件做个性化权限校验的场景。

方案二:全局路由resolve拦截(统一处理)

如果想给所有路由统一加权限校验,不用每个组件都写钩子,可以在路由配置时用resolve属性,它会在路由加载前执行:

angular.module('yourApp').config(function($routerProvider, $q) {
  $routerProvider
    // 受保护的路由
    .when('/dashboard', {
      component: 'protectedDashboard',
      resolve: {
        // 这里的resolve依赖会在路由激活前执行
        authCheck: function($router, AuthService) {
          // 排除不需要校验的路由(比如登录页、403页)
          if (AuthService.isGuest()) {
            $router.navigate(['Forbidden']);
            // 返回rejected的Promise,阻止路由继续加载
            return $q.reject('无访问权限');
          }
          return true;
        }
      }
    })
    // 403页面路由
    .when('/forbidden', {
      component: 'forbiddenPage'
    });
});
  • 如果resolve里的函数返回rejected的Promise,路由会被取消,同时我们可以在里面完成重定向。
  • 要是想给所有路由批量加这个校验,可以封装一个通用的resolve函数,避免重复代码。

方案三:全局父组件统一拦截(更简洁)

创建一个根组件作为所有路由的父容器,在这个父组件的$routerOnActivate里做全局权限校验,所有子路由都会继承这个逻辑:

angular.module('yourApp').component('appRoot', {
  template: '<ng-outlet></ng-outlet>', // 子路由的渲染出口
  controller: function($router, AuthService) {
    this.$routerOnActivate = function(nextRoute) {
      // 定义不需要校验的路由白名单
      const whitelist = ['Login', 'Forbidden', 'Home'];
      
      if (!whitelist.includes(nextRoute.routeName) && !AuthService.hasAccess(nextRoute.routeName)) {
        $router.navigate(['Forbidden']);
      }
    };
  }
});

然后把根路由指向这个组件:

$routerProvider.root({
  component: 'appRoot'
});

这个方案最适合全局统一权限规则的场景,一次配置全路由生效。

最后再提醒一句:ngComponentRouter和ngRoute是完全独立的实现,千万不要混用它们的API哦!

内容的提问来源于stack exchange,提问作者Renaud is Not Bill Gates

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:23:27