为什么Angular路由跳转时路由守卫(Guard)未被触发?
问题根因
- 登出操作执行时,你当前处于
/路由下,调用this.router.navigate(["/"])属于同路由地址导航,Angular默认路由策略会跳过守卫触发流程,也不会重新初始化当前路由对应的组件,因此你配置的canActivate守卫不会执行。 - 你的路由守卫实现了
CanLoad接口,但并未在根路由配置中注册该守卫,首次未登录访问站点时也不会阻止Shell模块的加载,属于配置遗漏。
修复方案
修改AppModule中RouterModule.forRoot的配置即可:
@NgModule({ declarations: [AppComponent], imports: [ BrowserModule, RouterModule.forRoot([ { path: "", loadChildren: () => Promise.resolve(ShellModule), canActivate: [IsLoggedInGuard], canLoad: [IsLoggedInGuard], // 补全CanLoad守卫注册 runGuardsAndResolvers: "always" // 配置该路由始终触发守卫和解析器 }, { path: "auth", loadChildren: () => Promise.resolve(AuthModule) } ], { onSameUrlNavigation: "reload" // 全局开启同地址导航的重载逻辑 }) ], providers: [IsLoggedInGuard], bootstrap: [AppComponent] }) export class AppModule {}
如果不想全局开启同路由重载,也可以在登出跳转时添加随机查询参数强制触发导航更新,可选实现如下:
logout() { console.log("in logout"); loggedIn = false; // 添加时间戳参数让路由判定为新的导航,触发守卫 this.router.navigate(["/"], { queryParams: { _t: Date.now() } }); }
验证逻辑
修改完成后点击登出按钮,会触发IsLoggedInGuard的canActivate钩子,检测到loggedIn为false后自动跳转到/auth登录页,符合你的预期逻辑。
内容的提问来源于stack exchange,提问作者Jon Sud
相关产品推荐
相关产品推荐

