React Native带Authorization头的Fetch请求偶发401未授权问题求助
问题分析
这个现象真的挺诡异的——一抓包问题就消失,不抓就偶尔冒出来401,这大概率是移动端浏览器的HTTP缓存在搞鬼。你是重复跳转同一页面发起相同的GET请求,移动端浏览器很可能会对这类请求做缓存复用,而缓存的请求不会带上你后续设置的Authorization头,自然就触发了Laravel Passport的未授权校验。
Postman没问题是因为它默认不会缓存请求,每次都是发送全新的带token请求,所以不会踩这个坑。
解决方案
针对缓存问题,你可以从这几个方向入手解决:
1. 给Fetch请求强制禁用缓存
修改你的Fetch配置,明确告诉浏览器不要缓存这个请求:
fetch(requestUrl, { method: "get", cache: 'no-store', // 直接禁用缓存,每次都发新请求 headers: new Headers({ 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded', 'Authorization': 'Bearer ' + token, 'Cache-Control': 'no-cache, no-store, must-revalidate' // 额外添加缓存控制头,双重保险 }) })
cache: 'no-store'是Fetch API的标准配置,会强制浏览器不缓存任何请求和响应;Cache-Control头则是给服务端和浏览器双端的缓存指令,确保不会复用旧请求。
2. 给请求URL添加唯一标识
如果上面的配置还是有问题,可以给请求URL拼接一个时间戳,让每次请求的URL都不一样,从根源上避免浏览器缓存:
// 拼接时间戳,确保每次URL唯一 var requestUrl = _api + 'GetMyProduct?' + param + '&t=' + Date.now();
这样即使浏览器想缓存,也因为URL不同而无法复用旧请求,每次都会发送带最新token的新请求。
3. 验证问题根源(可选)
你可以去Laravel的日志里查看出现401的请求详情,确认这些请求是否真的没有携带Authorization头。如果日志里显示请求头中没有Bearer token,那就能100%确认是缓存导致的问题,上面的方案肯定有效。
为什么抓包后问题消失?
抓包工具在捕获请求时,通常会修改浏览器的请求处理逻辑,强制禁用缓存或者代理请求,相当于间接帮你绕过了浏览器的缓存机制,所以问题就暂时消失了——这也反过来验证了缓存是罪魁祸首。
内容的提问来源于stack exchange,提问作者Darren Lau
相关产品推荐
相关产品推荐

