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

Angular刷新或直接输入URL时ActivatedRouteSnapshot的data属性为空问题

问题根因

你在父路由(path: '')和子路由上都配置了同一个AuthGuard,Angular路由守卫的执行顺序是从上到下、先父后子:

  • 页面刷新/直接输入URL访问时,首先触发父路由的AuthGuard,此时传入canActivate方法的route参数是父路由的ActivatedRouteSnapshot实例,本身没有配置data属性,自然读取不到子路由的permissions和路径配置
  • 应用内点击路由链接跳转时,父路由守卫已经在前序导航中完成校验,触发子路由守卫时传入的是子路由的快照,所以可以正常读取data

解决方案

方案1:调整守卫挂载逻辑(最推荐)

移除父路由上的AuthGuard,改用canActivateChild配置统管所有子路由的鉴权,守卫触发时会直接传入匹配到的子路由快照:

const routes: Routes = [
  {
    path: '',
    canActivateChild: [AuthGuard], // 替换原来的canActivate
    component: DefaultLayoutComponent,
    children: [
      // 子路由配置保持不变
    ]
  }
];

修改后子路由的AuthGuard可以保留也可以移除,canActivateChild会对所有子路由生效。

方案2:父守卫中递归获取最深子路由快照

如果必须保留父路由的canActivate配置,可以在守卫中递归读取到最终匹配的子路由快照再拿配置:

@Injectable({ providedIn: 'root' })
export class AuthGuard implements CanActivate {
  constructor(
    private router: Router,
    private accountService: AccountService
  ) { } // 注意:守卫不需要注入ActivatedRoute,直接用入参的route即可

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    // 递归获取最深层级的子路由快照
    const getDeepestRoute = (snapshot: ActivatedRouteSnapshot): ActivatedRouteSnapshot => {
      return snapshot.firstChild ? getDeepestRoute(snapshot.firstChild) : snapshot;
    }
    const targetRoute = getDeepestRoute(route);
    const path = targetRoute.routeConfig?.path;
    const permissions = targetRoute.data["permissions"];
    // 后续鉴权逻辑
  }
}

内容的提问来源于stack exchange,提问作者Developerzzz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 19:39:02