React中CSRF Token设置后组件无法获取的问题求助
在管理应用所有接口的profilesApi.ts文件中,我编写了setCsrfToken函数来设置CSRF Token,代码如下:
async function setCsrfToken() { try { const response = await axiosInstance.get(`/profiles/get_csrf_token/`); console.log('Response from CSRF token endpoint:', response.data); const csrftoken = Cookies.get('csrftoken'); console.log('CSRF token retrieved from cookies:', csrftoken); if (csrftoken) { axiosInstance.defaults.headers.common['X-CSRFToken'] = csrftoken; console.log('CSRF token set in axios instance'); console.log('CSRF just set:', axiosInstance.defaults.headers.common['X-CSRFToken']); } else { console.error('No CSRF token found in cookies'); } } catch (error) { console.error('Error initializing CSRF token:', error); } }
函数日志显示已成功从Cookie获取并设置Token:
Response from CSRF token endpoint: {message: 'CSRF cookie set'} profilesApi.ts:30 CSRF token retrieved from cookies: 0tChouzkTCx3sI86M9HQg9kbm5Lvfr1L profilesApi.ts:33 CSRF token set in axios instance profilesApi.ts:34 CSRF just set: 0tChouzkTCx3sI86M9HQg9kbm5Lvfr1L
但在Login组件中,调用setCsrfToken后打印axiosInstance.defaults.headers.common['X-CSRFToken']始终为undefined,按钮点击打印结果也一样。Cookie中的Token能被API文件正确获取设置,但组件中无法读取到该请求头值。
确认axiosInstance的一致性
检查profilesApi.ts中的axiosInstance是否是导出的单例,Login组件是否导入的是同一个实例,而非重新创建新的axios实例。如果两处的实例不是同一个,组件自然读取不到API文件中设置的headers。修正异步时序问题
setCsrfToken是异步函数,直接在useEffect中调用后立即打印,会因为函数未执行完成而拿到undefined。需要等待异步操作完成:useEffect(() => { const initCsrf = async () => { await setCsrfToken(); console.log(axiosInstance.defaults.headers.common['X-CSRFToken']); }; initCsrf(); }, []);按钮点击时也同理,确保先等待
setCsrfToken执行完毕再读取值。排查是否有headers覆盖逻辑
检查项目中是否有其他代码(比如全局请求拦截器、其他API函数)修改了axiosInstance的headers,导致X-CSRFToken被覆盖为undefined。可以添加请求拦截器验证请求发出时的headers:axiosInstance.interceptors.request.use(config => { console.log('实际请求headers:', config.headers); return config; });推荐更可靠的动态设置方式
放弃手动修改defaults.headers.common,改用请求拦截器每次请求前动态从Cookie获取并设置Token,避免实例共享导致的同步问题:// 在axiosInstance初始化时添加拦截器 axiosInstance.interceptors.request.use(config => { const csrftoken = Cookies.get('csrftoken'); if (csrftoken) { config.headers['X-CSRFToken'] = csrftoken; } return config; });这样无需单独调用
setCsrfToken,每次请求都会自动处理Token,也不会出现组件读取不到的问题。
内容的提问来源于stack exchange,提问作者Alejandro Veintimilla

