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

路由守卫实现后页面刷新丢失路由信息,重定向至首页问题求助

路由权限守卫刷新页面时丢失路由信息,重定向至根路径

实现基于用户角色的路由权限守卫后,出现以下异常:

  • 浏览器刷新页面或直接通过URL加载页面时,会被重定向至index.html,currentUrl显示为"/",原路由信息丢失
  • 页面间正常导航时组件加载无异常

路由权限守卫代码

canActivate(
  next: ActivatedRouteSnapshot,
  state: RouterStateSnapshot
): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
  const user = this._authService._user?.profile.sub;
  const route = next.routeConfig?.path?.split('/')[0];
  const currentUrl = this._router.url;

  return this.hasRight(user, route);
}

private hasRight(currentUserId: any, route: any): Promise<boolean | UrlTree> {
  return new Promise<boolean | UrlTree>((resolve, reject) => {
    this._securityService.apiSecurityHasRightPost(currentUserId, route).subscribe(
      (response: BooleanResponse) => {
        if (response.result!) {
          resolve(true);
        } else {
          resolve(this._router.createUrlTree(['/unauthorized']));
        }
      },
      (error) => {
        console.error('Error', error);
        resolve(false);
      }
    );
  });}

子模块路由配置(应用守卫方式)

const routes: Routes = [
    {
        path: '', component: MainComponent, children: [
            { path: '', redirectTo: 'dashboard', pathMatch: 'full' },
            { path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] },
            { path: 'test', component: NewtestpageComponent,canActivate:[RouteAccessControlGuard]},
            { path: 'redirect', component: MainRedirectComponent },
            { path: 'brand', component: BrandComponent,canActivate:[RouteAccessControlGuard]  },
    ]}
];

index.html中的base href

<base href="/">

根路由模块代码

const AUTH_ROUTES: Routes= [
  { path: '', redirectTo:'unauthorized', pathMatch:'full'}, 
  { path: 'unauthorized', component: UnauthorizedComponent },
  { path: 'signin-callback', component: SigninCallbackComponent },
  { path: 'signout-callback', component: SignoutCallbackComponent },
  { path: 'silent-callback', component: SilentCallbackComponent },
];
const routes: Routes = [
  { path: '', redirectTo:'main', pathMatch:'full'}, 
  { path: '', component: AuthLayoutComponent, children:AUTH_ROUTES}, 
  { path: 'main',loadChildren: ()=>import('./main/main.module').then(m => m.MainModule), canActivate:[AuthGuard]},
  { path: 'showroom/:id', component: ShowroomComponent},
];

@NgModule({
  imports: [RouterModule.forRoot(routes,{
    onSameUrlNavigation: 'reload',
  })]
})

已尝试的方案

  • 调整异步逻辑,将hasRight方法移至服务和解析器中,问题未解决

问题排查与解决方案

1. 修复路由信息获取逻辑

刷新页面时next.routeConfig?.path可能为空,导致权限校验失败触发默认重定向。改用state.url获取目标路由:

canActivate(
  next: ActivatedRouteSnapshot,
  state: RouterStateSnapshot
): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
  const user = this._authService._user?.profile.sub;
  // 从完整URL提取目标路由(示例:/main/test -> test)
  const targetPath = state.url.split('/')[2];

  if (!user) {
    return this._router.createUrlTree(['/unauthorized']);
  }

  return this.hasRight(user, targetPath);
}

2. 修正错误场景处理逻辑

当前请求出错时返回false会触发Angular默认重定向,改为明确重定向到未授权页面:

private hasRight(currentUserId: any, route: any): Promise<boolean | UrlTree> {
  return new Promise<boolean | UrlTree>((resolve) => {
    if (!route) {
      resolve(this._router.createUrlTree(['/unauthorized']));
      return;
    }
    this._securityService.apiSecurityHasRightPost(currentUserId, route).subscribe(
      (response: BooleanResponse) => {
        resolve(response.result! ? true : this._router.createUrlTree(['/unauthorized']));
      },
      (error) => {
        console.error('权限校验请求出错', error);
        resolve(this._router.createUrlTree(['/unauthorized']));
      }
    );
  });
}

3. 调整根路由优先级

根路由存在两个空路径路由,导致匹配异常,修改为:

const routes: Routes = [
  { path: '', redirectTo:'main', pathMatch:'full'}, 
  // 给AUTH_ROUTES父路由指定非空路径
  { path: 'auth', component: AuthLayoutComponent, children:AUTH_ROUTES}, 
  { path: 'main',loadChildren: ()=>import('./main/main.module').then(m => m.MainModule), canActivate:[AuthGuard]},
  { path: 'showroom/:id', component: ShowroomComponent},
];

4. 移除冗余路由配置

onSameUrlNavigation: 'reload'可能导致刷新时路由重复解析,移除该配置:

@NgModule({
  imports: [RouterModule.forRoot(routes)]
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 02:43:11