React Native关闭WebView后调用API出现Cookie丢失问题求助
我的问题是这样的:我在React Native项目里用Axios调用API,已经设置了withCredentials: true,原本能正常带上Cookie调用example.com域名的接口,一切都没问题。但在Android设备上运行Metro时,做完下面这两步操作后,再调用API就报错了:
- 打开App内的WebView(用的是react-native-webview,已经开了
sharedCookiesEnabled: true) - 等WebView的导航状态变化后做了些操作,关闭WebView再去调API,就出现Cookie丢失导致的请求失败了。
下面是我整理的几个可能的原因和对应的解决思路,供你参考:
WebView和App的Cookie共享冲突
虽然开了sharedCookiesEnabled,但WebView在导航过程中可能会修改甚至覆盖App层面的Cookie,尤其是当WebView访问的域名和API域名一致时更容易出现这个问题。
解决办法:可以在WebView准备关闭的时候,注入JS脚本拿到WebView里的Cookie,再同步到App的Cookie存储中。比如用react-native-cookies这个库,代码大概是这样:// 先拿到WebView的引用 const webViewRef = useRef(null); const handleNavigationStateChange = (newState) => { // 判断WebView加载完成且是目标域名页面 if (!newState.loading && newState.url.includes('example.com')) { // 注入JS获取当前Cookie webViewRef.current.injectJavaScript(`document.cookie;`).then(cookies => { // 同步到App的Cookie存储 CookieManager.setFromResponse('https://example.com', cookies) .then(() => console.log('Cookie同步成功')) .catch(err => console.error('Cookie同步失败', err)); }); } };Android系统的Cookie存储隔离
Android里WebView的Cookie存储和Axios底层用的OkHttp的Cookie存储默认可能是隔离的,就算开了共享也可能有延迟或者覆盖问题。
解决办法:如果是裸项目,可以自定义OkHttp的CookieJar,让它和WebView用同一个Cookie管理器;如果是Expo项目,可以用expo-cookies来统一管理。另外要注意如果Cookie是HttpOnly的,前端JS拿不到,得通过原生代码来同步。Metro热重载的干扰
开发环境下Metro的热重载可能会重置Cookie存储的状态,尤其是WebView操作后热重载,很容易丢Cookie。
解决办法:测试的时候可以先关掉热重载,或者操作完WebView后重启Metro试试,也可以打包成生产包测试,看是不是只有开发环境才会出现这个问题。Axios的Cookie缓存问题
Axios可能会缓存之前的Cookie状态,WebView修改Cookie后它没及时更新。
解决办法:每次调用API前可以清除Axios的缓存,或者重新创建Axios实例,确保每次请求都用最新的Cookie。
备注:内容来源于stack exchange,提问作者Suppose

