React项目Axios拦截器配置:无accessToken时清存储并路由到登录页
React SPA中Axios拦截器配置(无刷新跳转登录页)
核心实现逻辑
- 在Axios请求拦截器中前置检查
localStorage内的accessToken - 依赖React Router的路由能力实现无刷新跳转,避免使用
window.location类方法 - 无token时清空
localStorage并导航至登录页,同时终止当前请求
具体代码实现
方案一:适配React Router v6(使用useNavigate钩子)
先创建Axios实例,通过自定义Hook注入路由导航能力:
// src/utils/axiosInstance.js import axios from 'axios'; import { useNavigate } from 'react-router-dom'; import { useEffect } from 'react'; // 创建全局Axios实例 const axiosInstance = axios.create({ baseURL: process.env.REACT_APP_API_BASE_URL, }); // 导出Hook用于配置拦截器 export const useAxiosInterceptor = () => { const navigate = useNavigate(); useEffect(() => { // 添加请求拦截器 const interceptorId = axiosInstance.interceptors.request.use( (config) => { const accessToken = localStorage.getItem('accessToken'); if (!accessToken) { // 清空当前域名下的localStorage localStorage.clear(); // 无刷新跳转登录页 navigate('/auth/login'); // 终止当前请求,避免无效请求发送 return Promise.reject(new Error('未检测到登录状态,已跳转至登录页')); } // 可选:将token加入请求头 config.headers.Authorization = `Bearer ${accessToken}`; return config; }, (error) => Promise.reject(error) ); // 组件卸载时移除拦截器,防止内存泄漏 return () => axiosInstance.interceptors.request.eject(interceptorId); }, [navigate]); return axiosInstance; };
在业务组件中使用:
// src/components/ExampleComponent.js import { useAxiosInterceptor } from '../utils/axiosInstance'; const ExampleComponent = () => { const api = useAxiosInterceptor(); const fetchData = async () => { try { const res = await api.get('/api/data'); // 处理响应数据 } catch (err) { // 处理错误(如跳转后的提示) } }; return <button onClick={fetchData}>获取数据</button>; }; export default ExampleComponent;
方案二:适配React Router v5(使用history实例)
先创建独立的history实例:
// src/utils/history.js import { createBrowserHistory } from 'history'; export default createBrowserHistory();
配置Axios拦截器:
// src/utils/axiosInstance.js import axios from 'axios'; import history from './history'; const axiosInstance = axios.create({ baseURL: process.env.REACT_APP_API_BASE_URL, }); // 全局请求拦截器 axiosInstance.interceptors.request.use( (config) => { const accessToken = localStorage.getItem('accessToken'); if (!accessToken) { localStorage.clear(); // 无刷新跳转 history.push('/auth/login'); return Promise.reject(new Error('未登录,已跳转至登录页')); } config.headers.Authorization = `Bearer ${accessToken}`; return config; }, (error) => Promise.reject(error) ); export default axiosInstance;
在根组件中绑定Router:
// src/App.js import { Router, Switch, Route } from 'react-router-dom'; import history from './utils/history'; import Login from './components/Login'; import Dashboard from './components/Dashboard'; function App() { return ( <Router history={history}> <Switch> <Route path="/auth/login" component={Login} /> <Route path="/dashboard" component={Dashboard} /> </Switch> </Router> ); } export default App;
关键注意事项
- 拦截器中必须终止当前请求,避免无效请求发送到后端
- 组件卸载时需移除拦截器,防止内存泄漏
- 统一配置Axios实例,便于团队协作维护
内容的提问来源于stack exchange,提问作者Sohan Paliyal Simprosys
相关产品推荐
相关产品推荐

