news 2026/5/6 5:10:57

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/4/27 21:46:47

HY-Motion 1.0多场景方案:教育、游戏、影视、健康四大领域落地图谱

HY-Motion 1.0多场景方案&#xff1a;教育、游戏、影视、健康四大领域落地图谱 1. 为什么动作生成突然变得“能用了”&#xff1f; 过去几年&#xff0c;你可能见过不少文生图、文生视频的演示&#xff0c;但提到“文字变动作”&#xff0c;第一反应往往是——这真的能用吗&a…

作者头像 李华
网站建设 2026/5/3 18:36:56

rs485modbus协议源代码入门必看:零基础快速理解通信机制

以下是对您提供的博文内容进行深度润色与结构重构后的技术文章。整体风格已全面转向真实工程师口吻 教学博主视角 工程实战语境&#xff0c;彻底去除AI生成痕迹、模板化表达和空洞术语堆砌&#xff0c;代之以逻辑清晰、层层递进、有血有肉的技术叙述。全文采用“问题驱动→原…

作者头像 李华
网站建设 2026/5/4 20:59:40

极速网络加速全攻略:Fast-GitHub插件提升开发效率指南

极速网络加速全攻略&#xff1a;Fast-GitHub插件提升开发效率指南 【免费下载链接】Fast-GitHub 国内Github下载很慢&#xff0c;用上了这个插件后&#xff0c;下载速度嗖嗖嗖的~&#xff01; 项目地址: https://gitcode.com/gh_mirrors/fa/Fast-GitHub 在当今数字化开发…

作者头像 李华
网站建设 2026/5/4 20:59:01

CogVideoX-2b金融场景:K线动态演化、风险模型可视化短视频生成

CogVideoX-2b金融场景&#xff1a;K线动态演化、风险模型可视化短视频生成 1. 为什么金融从业者需要会“看动图”的AI视频工具&#xff1f; 你有没有遇到过这些场景&#xff1a; 向客户解释一个复杂的波动率曲面时&#xff0c;PPT里的静态图表总让人眼神放空&#xff1b;内部…

作者头像 李华
网站建设 2026/5/4 20:59:37

res-downloader技术白皮书:从原理到实践的完整指南

res-downloader技术白皮书&#xff1a;从原理到实践的完整指南 【免费下载链接】res-downloader 资源下载器、网络资源嗅探&#xff0c;支持微信视频号下载、网页抖音无水印下载、网页快手无水印视频下载、酷狗音乐下载等网络资源拦截下载! 项目地址: https://gitcode.com/Gi…

作者头像 李华
网站建设 2026/5/4 20:59:33

ARM平台Unity游戏兼容性实战:Box64突破OpenGL 3+技术壁垒

ARM平台Unity游戏兼容性实战&#xff1a;Box64突破OpenGL 3技术壁垒 【免费下载链接】box64 Box64 - Linux Userspace x86_64 Emulator with a twist, targeted at ARM64 Linux devices 项目地址: https://gitcode.com/gh_mirrors/bo/box64 在ARM架构设备上运行Unity游戏…

作者头像 李华