React Native iOS端Fetch带Cookie首请求成功后续401问题排查
React Native iOS Fetch请求首次成功后续401问题排查与解决
问题描述
我正以学习为目的重写一个小型React Native应用,需要从第三方服务器拉取数据,该服务器要求使用硬编码Cookie(无需握手验证)。这个Cookie在其他iOS原生版本的同应用中可以重复正常使用,但在React Native iOS版本里,首次Fetch请求能成功,后续请求全部返回401错误。我想搞清楚:
A)为什么只有首次请求有效?
B)怎么修改代码让每次请求都成功?
请求代码(已脱敏):
const onFetchPressed = async () => { try { const urlString = blahblah const response = await fetch(urlString, { method: 'GET', credentials: 'include', headers: { "Host": "blahblah", "Accept": "application/json", "Accept-Encoding": "gzip, deflate, br", "User-Agent": "blahblah", "Connection": "keep-alive", "Content-Type": "application/json", "Cookie": "session_id=shhh-secret-stuff-here" }, }); const json = await response.json(); setUsers(json); console.debug(json) } catch (error) { console.error(error); } finally { } }
A)首次请求有效、后续401的原因
- 你设置了
credentials: 'include',这个配置会让React Native的Fetch自动管理Cookie。首次请求时手动传入的硬编码Cookie能被服务器识别,正常响应;但服务器可能在响应头返回Set-Cookie,覆盖了原本的硬编码Cookie。后续请求时,Fetch会自动使用服务器返回的新Cookie,而这个新Cookie大概率无效或过期,因此触发401。 - iOS的网络安全策略限制也可能是原因:如果服务器返回的Cookie未设置
Same-Site=None; Secure,在React Native的Fetch环境下,跨域请求的后续请求不会携带该Cookie,导致权限验证失败。
B)解决方法
方案1:禁用自动Cookie管理(推荐)
移除credentials: 'include'配置,强制每次请求都携带你硬编码的有效Cookie。这样Fetch不会自动处理服务器返回的Set-Cookie,所有请求都会使用你指定的Cookie:
const onFetchPressed = async () => { try { const urlString = 'blahblah'; const response = await fetch(urlString, { method: 'GET', // 移除credentials,避免自动管理Cookie headers: { "Host": "blahblah", "Accept": "application/json", "Accept-Encoding": "gzip, deflate, br", "User-Agent": "blahblah", "Connection": "keep-alive", "Content-Type": "application/json", "Cookie": "session_id=shhh-secret-stuff-here" }, }); const json = await response.json(); setUsers(json); console.debug(json) } catch (error) { console.error(error); } }
方案2:强制覆盖自动管理的Cookie
如果必须保留credentials: 'include',可以确保每次请求的Cookie头优先级高于自动管理的Cookie。不过这种方式需要额外处理Cookie冲突,不如方案1直接。
额外说明
由于你不拥有服务器,无法直接控制服务器返回的Set-Cookie头,所以修改Same-Site属性的思路不可行,优先用方案1解决问题更高效。
内容的提问来源于stack exchange,提问作者Janene Pappas
相关产品推荐
相关产品推荐

