如何判断全局Axios实例是否存在Authorization头并确保请求前已设置
解决方案
先分析你现有代码的问题
你当前的写法会重复添加请求拦截器——每次token更新时,都会注册一个新的拦截器,最终导致多个拦截器叠加执行,可能出现旧token覆盖新token、请求头重复设置的问题,这是核心隐患。
最优方案:全局维护token,只注册一次拦截器
把token的维护和拦截器逻辑统一放在Axios实例的定义文件中,避免重复注册拦截器,确保所有请求都能拿到最新的token。
1. 修改azureServices.js
import axios from 'axios'; // 创建全局Graph API Axios实例 export const graphAxios = axios.create({ baseURL: 'https://graph.microsoft.com/v1.0/' }); // 全局存储当前有效的token let currentAccessToken = null; // 只注册一次请求拦截器,每次请求时自动读取最新token graphAxios.interceptors.request.use((config) => { if (currentAccessToken) { config.headers.Authorization = `Bearer ${currentAccessToken}`; } return config; }, (error) => { return Promise.reject(error); }); // 提供更新token的方法,供外部调用 export const updateGraphAccessToken = (token) => { currentAccessToken = token?.access_token || null; };
2. 根组件中更新token
import { updateGraphAccessToken } from '../../services/azureServices'; const { data: token, isLoading } = trpc.auth.getSessionToken.useQuery(); useEffect(() => { // 拿到token后直接更新全局存储的token updateGraphAccessToken(token); }, [token]);
这样不管你在应用的哪个位置调用graphAxios,请求都会自动带上最新的Authorization头,完全不需要担心头未设置的问题。
补充:确保请求发起时token已就绪
如果某些页面/组件需要在token加载完成后才能发起请求,可以通过以下方式控制:
方式1:组件内依赖token触发请求
import { graphAxios } from '../../services/azureServices'; const { data: token, isLoading: tokenLoading } = trpc.auth.getSessionToken.useQuery(); const [graphData, setGraphData] = useState(null); useEffect(() => { // 未加载到token时不发起请求 if (!token || tokenLoading) return; const fetchGraphData = async () => { const res = await graphAxios.get('/me'); setGraphData(res.data); }; fetchGraphData(); }, [token, tokenLoading]);
方式2:拦截器中拦截无token的请求
在azureServices.js的拦截器中添加无token的处理逻辑,避免发送无效请求:
graphAxios.interceptors.request.use((config) => { if (!currentAccessToken) { // 取消请求并抛出错误,可在调用处捕获处理(比如跳转到登录页) return Promise.reject(new Error('未获取到访问令牌,请重新登录')); } config.headers.Authorization = `Bearer ${currentAccessToken}`; return config; });
内容的提问来源于stack exchange,提问作者astr
相关产品推荐
相关产品推荐

