Axios:部分iOS设备上特定请求未设置Authorization头的问题求助
碰到这种仅特定请求在部分iOS设备上出问题的情况,确实挺头疼的——毕竟其他请求都正常,说明拦截器的逻辑大体是对的。我给你梳理几个针对性的排查思路和解决方案,你可以一步步试:
1. 先给拦截器加日志,定位问题环节
首先得搞清楚,在出问题的iOS设备上,这个请求到底有没有走到Authorization头的设置逻辑里。你可以在请求拦截器里加几个日志,把关键信息打出来:
api.interceptors.request.use( function (config) { // 打印当前请求的URL,确认是否和预期一致 console.log('[Interceptor] Request URL:', config.url); // 打印要读取的token const accessToken = localStorage.getItem('token'); console.log('[Interceptor] Access Token:', accessToken); if (config.url !== "/register") { if (accessToken) { config.headers.Authorization = "Bearer " + accessToken; console.log('[Interceptor] Set Authorization:', config.headers.Authorization); } else { console.log('[Interceptor] No access token found'); } } else { console.log('[Interceptor] Skipping auth for register'); } return config; }, function (error) { console.log('[Interceptor] Request error:', error); return Promise.reject(error); } );
让出现问题的用户帮忙提供这些日志,就能知道是URL匹配出了问题、token没读到,还是头根本没设置上。
2. 换掉手动拼接URL的方式,改用Axios的params配置
你现在的getSessions是直接拼接URL参数的,这种方式很容易因为参数里的特殊字符(比如时间戳的格式、特殊符号)导致URL在iOS WebView里被解析成异常格式,甚至被Axios误判路径。建议改成Axios官方推荐的参数传递方式:
export function getSessions(context, payload) { return new Promise((resolve, reject) => { api.get(`/sessions/${payload.sportId}/`, { params: { begin: payload.period.from, end: payload.period.to } }) .then(({ data }) => { resolve(data); }) .catch((error) => { reject(error); }); }); }
Axios会自动帮你处理参数的URL编码,确保请求路径是标准格式,避免因为URL解析问题绕过拦截器。
3. 排查iOS WebView的缓存问题
部分iOS设备的WebView会对GET请求做激进缓存,可能之前某次不带Authorization头的请求被缓存了,后续直接读取缓存响应,根本没触发新的请求。你可以试试给这个请求加缓存禁用的头,或者加个随机时间戳参数:
export function getSessions(context, payload) { return new Promise((resolve, reject) => { api.get(`/sessions/${payload.sportId}/`, { params: { begin: payload.period.from, end: payload.period.to, t: Date.now() // 加时间戳避免缓存 }, headers: { 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0' } }) .then(({ data }) => { resolve(data); }) .catch((error) => { reject(error); }); }); }
同时也可以检查服务器端对这个接口的缓存设置,是不是给了过长的缓存有效期。
4. 检查iOS版本和WebView类型
如果你的应用是混合应用(比如用Cordova/Capacitor),要确认是不是用了WKWebView——UIWebView已经被苹果废弃,存在不少兼容性问题。如果是纯Web应用,问问用户的iOS版本(比如iOS 12及以下的Safari有一些已知的HTTP头处理bug),可以试试换一种设置Authorization头的写法:
// 替换原来的设置方式 config.headers.common['Authorization'] = `Bearer ${accessToken}`;
5. 确认localStorage的可用性
iOS的隐私模式下,localStorage可能会被限制读取,或者某些低版本系统在内存不足时会清空localStorage。你可以在拦截器里确认token是否存在,也可以考虑把token存在Cookie里作为备选方案。
内容的提问来源于stack exchange,提问作者GontranMacedoine

