React Router Switch访问/contact等路由触发首页相同请求问题
问题根因
你的路由配置存在两个问题,导致/contact和/apropos路由永远无法命中:
react-router的Switch组件会按代码顺序从上到下匹配路由,一旦命中第一个符合规则的路由就直接终止匹配,你把匹配范围更宽泛的博客列表路由放在了静态页面路由前面- 博客分页路由
<Route path="/:page([\d]+)?" component={BlogPage}/>没有加exact精确匹配属性,结合可选参数的规则,会错误拦截所有以/开头的路径。
匹配逻辑说明
/:page([\d]+)?这个路径规则在未开启exact时:
- 只要访问路径以
/开头就满足基础匹配条件 - 后面的
:page参数是可选的,要求参数为数字的正则仅在参数存在时才会校验,参数不存在时直接判定匹配成功 - 因为没有精确匹配要求,访问
/contact、/apropos时,路径开头的/已经满足匹配要求,后面的contact、apropos字符串会被直接忽略,最终直接渲染BlogPage组件,根本不会走到后面定义的联系、关于页面路由。
修复方法
推荐用第一种方案,符合路由配置的通用最佳实践:
方案一:调整路由顺序+补全exact属性
把路径更明确的静态路由、动态路由放在宽泛匹配的路由前面,同时给根分页路由加上exact:
<Switch> <Route path="/post/:id([\d]+)" component={PostPage}/> <Route path="/tag/:tag/:page([\d]+)?" component={BlogPage}/> {/* 静态页面路由移到宽泛的分页路由之前 */} <Route exact path="/contact" component={Contact}/> <Route exact path="/apropos" component={About}/> {/* 分页路由加exact,仅精确匹配/和/1、/2这类纯数字分页路径 */} <Route exact path="/:page([\d]+)?" component={BlogPage}/> <Route path="*" component={() => ( <Container> <Row> <h1>404</h1> </Row> </Container> )} /> </Switch>
方案二:仅给分页路由加exact(不推荐)
如果不调整路由顺序,只给/:page([\d]+)?路由加上exact属性,也能让/contact、/apropos正常匹配。但这种写法后续新增其他静态路由时,很容易再次出现路由被前置宽泛规则拦截的问题,可维护性差。
生产环境额外配置提示
项目打包部署到生产环境后,如果直接在地址栏输入子路径出现404,需要给对应的Web服务器(Nginx、Apache、静态托管服务等)配置history路由 fallback 规则,将所有请求重定向到index.html,交由前端路由处理页面渲染。
内容的提问来源于stack exchange,提问作者user19271630
相关产品推荐
相关产品推荐

