news 2026/6/9 21:38:33

React Router 7 全局路由保护

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
React Router 7 全局路由保护

之前项目的路由保护是这样的:每个需要登录的页面都判断一下token,没有就跳转登录页。

// 之前:每个页面都要写 const SomePage = () => { const token = localStorage.getItem('token'); if (!token) { return <Navigate to="/login" />; } return <div>页面内容</div>; };

这样写有几个问题:

  1. 每个页面都要重复这个逻辑
  2. 万一漏了一个页面,就有安全漏洞
  3. 代码很乱,业务逻辑混在一起

后来我改成全局路由保护,清爽多了。

React Router 7 的新特性

React Router 7 推出了<BrowserRouter>basename和一些新特性,但最实用的是嵌套路由。

但我的方案不是在每个路由外面套<ProtectedRoute>,而是在main.jsx里套一个全局的:

// main.jsx <BrowserRouter> <ProtectedRoute> {/* 全局保护,只套一次 */} <ConfigProvider> <App /> </ConfigProvider> </ProtectedRoute> </BrowserRouter>

这样<App />里面的所有路由都会经过保护逻辑。

ProtectedRoute 的实现

ProtectedRoute组件要做三件事:

  1. 检查 token,没有就跳登录
  2. 检查路由是否合法(防止访问不存在的页面)
  3. 处理登录后跳回原页面的逻辑
const ProtectedRoute = ({ children }) => { const location = useLocation(); const pathname = location.pathname; // 1. 检查路由是否合法 const allowedRoutes = [ "/login", "/", "/chat", "/customer", "/review-dashboard", "/pdf-annotator/:id", ... ]; const isValidRoute = allowedRoutes.some(route => pathname === route || pathname.startsWith(`${route}/`) ); if (!isValidRoute) { return <Navigate to="/404" replace />; } // 2. 登录页面直接放行 if (pathname === "/login") { return <>{children}</>; } // 3. 检查 token const token = localStorage.getItem("token"); if (!token) { localStorage.setItem("pathname", pathname); // 保存原路径 return <Navigate to="/login" replace />; } // 4. 根路径重定向 if (pathname === "/") { return <Navigate to="/chat" replace />; } return <>{children}</>; };

这样写的好处:

  • 所有路由都在一个地方管理,不会漏
  • 未定义的路由自动跳 404
  • 登录后自动跳回原页面
但是有个坑:401 错误处理

用户登录后,token 会过期。这时候后端返回 401,我需要自动跳转到登录页。

但这个逻辑不能写在ProtectedRoute里,因为它只在路由切换时执行,不会响应 API 请求。

我把它写在了 Axios 拦截器里:

// request.js export let isRelogin = { show: false }; request.interceptors.response.use( (response) => { if (response.data.code === 401) { if (!isRelogin.show) { isRelogin.show = true; message.error('登录状态已过期'); localStorage.setItem("pathname", window.location.pathname); localStorage.removeItem("token"); window.location.href = "/login"; } } else if (response.data.code !== 200) { message.error(response.data.msg); return Promise.reject(response.data); } return response; }, (error) => { if (error.response?.status === 401) { localStorage.removeItem("token"); window.location.href = "/login"; } return Promise.reject(error); } );

这里有个坑:如果多个请求同时返回 401,会弹出多次错误提示。

我用了个isRelogin.show标志位,确保只弹一次:

export let isRelogin = { show: false }; if (response.data.code === 401) { if (!isRelogin.show) { // 只处理第一次 isRelogin.show = true; message.error('登录状态已过期'); window.location.href = "/login"; } }

登录成功后,记得重置这个标志位:

// 登录成功后 isRelogin.show = false;
懒加载怎么处理?

React Router 7 推荐用懒加载,但ProtectedRoute会阻止懒加载的组件渲染。

我的方案是:只懒加载页面组件,不懒加载ProtectedRoute

// App.jsx const HomePage = lazy(() => import("./view/HomePage")); const PDFAnnotatorDemo = lazy(() => import("./view/PDFAnnotatorDemo")); const App = () => { return ( <Suspense fallback={<PageLoading />}> <Routes> <Route path="/homepage" element={<HomePage />} /> <Route path="/pdf-annotator/:id" element={<PDFAnnotatorDemo />} /> ... </Routes> </Suspense> ); };

ProtectedRoutemain.jsx里,不会被懒加载,所以一开始就会加载。

最后的效果

现在的路由架构:

  • main.jsx:全局保护 + 登录页不懒加载
  • App.jsx:懒加载所有其他页面
  • request.js:401 自动跳登录

代码清爽多了,也不用担心漏保护某个页面。

几个踩坑总结
  1. 全局保护比单独保护好:一次套在main.jsx里就行
  2. 401 处理要防重复:用isRelogin.show标志位
  3. 路由白名单要维护:未定义的路由跳 404
  4. 懒加载不能保护 ProtectedRoute:它要最先加载
  5. 登录后要跳回原路径:用localStorage.pathname保存
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/9 6:36:03

零基础玩转阿里小云KWS:手把手教你实现语音唤醒功能

零基础玩转阿里小云KWS&#xff1a;手把手教你实现语音唤醒功能 你有没有试过对着智能设备说一句“小云小云”&#xff0c;它立刻从沉睡中醒来&#xff0c;准备听你吩咐&#xff1f;这种“一唤即应”的体验&#xff0c;背后不是魔法&#xff0c;而是一套精巧、稳定、开箱即用的…

作者头像 李华
网站建设 2026/6/6 16:34:05

Android Studio 毕业设计新手实战指南:从项目搭建到避坑全流程

Android Studio 毕业设计新手实战指南&#xff1a;从项目搭建到避坑全流程 摘要&#xff1a;许多计算机专业学生在毕业设计阶段首次使用 Android Studio&#xff0c;常因环境配置、项目结构混乱或调试困难而效率低下。本文面向零基础开发者&#xff0c;系统梳理 Android Studio…

作者头像 李华
网站建设 2026/6/4 17:44:50

手把手教程:用WuliArt Qwen-Image Turbo快速生成1024×1024高清图片

手把手教程&#xff1a;用WuliArt Qwen-Image Turbo快速生成10241024高清图片 你有没有试过——输入“水墨风少女执伞立于青石巷&#xff0c;细雨如丝&#xff0c;白墙黛瓦”&#xff0c;结果生成的图里伞是歪的、雨丝像面条、连墙都糊成一片灰&#xff1f; 不是你提示词写得不…

作者头像 李华
网站建设 2026/6/5 16:40:11

探索声波可视化:开源音频频谱分析工具的技术解密与实践指南

探索声波可视化&#xff1a;开源音频频谱分析工具的技术解密与实践指南 【免费下载链接】spek Acoustic spectrum analyser 项目地址: https://gitcode.com/gh_mirrors/sp/spek 在数字音频的无形世界中&#xff0c;我们如何才能"看见"声音的频率结构&#xff…

作者头像 李华
网站建设 2026/6/3 22:14:22

EdgeRemover:Windows系统彻底删除Edge的系统工具方案

EdgeRemover&#xff1a;Windows系统彻底删除Edge的系统工具方案 【免费下载链接】EdgeRemover PowerShell script to remove Microsoft Edge in a non-forceful manner. 项目地址: https://gitcode.com/gh_mirrors/ed/EdgeRemover 作为Windows系统默认浏览器&#xff0…

作者头像 李华