Angular Router**通配符路由无法匹配多级路径404问题
问题根因
该问题由Angular Router的深度优先、从上到下匹配规则和通配符作用域特性导致,和空路径搭配children的写法本身无关:
- Angular路由匹配时,一旦某层级的路由配置命中前缀匹配规则,就会进入该路由的子路由数组继续匹配,匹配失败时不会自动回退到同级路由数组寻找后续的通配符
- 你配置的
path: ''、挂载FullComponent的布局路由没有指定pathMatch,默认取prefix模式:空路径可以前缀匹配任意URL,因此所有未被前面login、register、根路径重定向规则命中的URL,都会直接进入该布局路由的children分支继续匹配 - 该布局路由的children数组中仅配置了2个懒加载业务路由,没有配置本层级的通配符兜底,因此访问
/a/b这类多级非法路径时,路由进入布局分支后找不到匹配项,又无法回到根路由层级命中你配置的全局**通配符,自然无法加载404页面 - 一级非法路径能正常命中404,是因为一级路径匹配时会先进入第一个空路径的懒加载模块分支,该模块内部未匹配到路由时会回退到根层级,刚好命中根层级的通配符;多级路径进入布局路由分支后多了一层路由嵌套,无法回退到根层级通配符。
排查思路
按以下顺序定位即可:
- 检查所有未指定
pathMatch的空路径父路由,确认是否因默认prefix模式提前截流了所有URL,导致后续同级通配符无法命中 - 逐层检查嵌套路由(包括懒加载模块内部的路由配置),确认每一层的路由数组末尾是否缺少本层级的通配符兜底配置
- 确认通配符
**的放置位置:必须是当前路由层级的最后一项,全局通配符仅能处理直接在根路由层级匹配失败的路径,无法处理被父路由截流到子分支后的匹配失败场景
解决方案
推荐使用常规后台布局路由的标准写法,改动最小:
- 给全局404页面配置明确的访问路径
- 在每一层嵌套路由(包括布局路由的children、所有懒加载业务模块的路由数组)的末尾,添加通配符规则,将匹配失败的路径重定向到全局404页面
修改后的根路由配置参考:
export const AppRoutes: Routes = [ {path: '', redirectTo: 'dashboard', pathMatch: 'full'}, {path: 'login', component: LoginComponent}, {path: 'register', component: RegisterComponent}, { path: '', component: FullComponent, canLoad: [LoginGuard], children: [ { path: '', loadChildren: () => import('./material-component/material.module').then(m => m.MaterialComponentsModule) }, {path: 'dashboard', loadChildren: () => import('./dashboard/dashboard.module').then(m => m.DashboardModule)}, // 布局层兜底:所有进入布局但未匹配到业务路由的路径,重定向到404 {path: '**', redirectTo: '/404', pathMatch: 'full'} ] }, {path: '404', component: PageNotFoundComponent}, // 根层兜底:所有未被前面规则命中的路径,重定向到404 {path: '**', redirectTo: '/404'} ];
补充注意点:
- 不要给带children的空路径布局路由设置
pathMatch: 'full',该配置要求URL剩余段完全为空才会命中,会导致布局下的所有子路由(比如dashboard)无法匹配 - 所有懒加载业务模块内部的路由数组末尾,也需要添加
{path: '**', redirectTo: '/404', pathMatch: 'full'}的兜底规则,避免模块内部匹配失败时出现空白页
内容的提问来源于stack exchange,提问作者chan yue
相关产品推荐
相关产品推荐

