react-native fetch() cookie 持续存在

问题描述 投票:0回答:3

我刚开始使用react-native 以及javascript 中的

fetch
api。我使用后端对我的应用程序进行身份验证,在我的 ios 模拟器中进行几次刷新后,应用程序会检查它是否在初始加载时通过后端进行了身份验证,令我惊讶的是,确实如此!这就引出了一个问题:react-native 和
fetch
api 中持续存在的位置和内容是什么?

javascript reactjs react-native cookies fetch-api
3个回答
32
投票
React Native 上的

fetch
是在本机级 API 之上实现的,并且whatwg 规范和众所周知的 github polyfill 略有不同。这意味着当发出实际的 HTTP 请求时,它是由 iOS 上的本机网络堆栈或 Android 上的OkHttp3 发出的,并且在每种情况下,都是由底层 ObjC 或 Java 代码处理和存储 cookie,远离 JS代码。

直到 2015 年 11 月的

此提交,cookie 根本无法在 Android 上正确保留,但自 RN 0.16 以来,无论您的 credential

 调用中的 
fetch
 设置如何,它们都在两个平台上都受支持。因此,会话 cookie 等可以开箱即用,如果您不希望保留任何内容,这可能会令人不安。如果您需要从 JS 操作 cookie,请查看 
react-native-cookies,它与底层 cookie 存储交互。


0
投票
RN 中的 Cookie 已完全损坏。您需要指定

credentials: "omit"

 来阻止 RN 进行糟糕的内置处理并自行完成。

请注意,cookie 本质上是附加的(多个

Set-Cookie

 标头应添加到该域的 cookie 中):

import setCookieParser from 'set-cookie-parser' const origFetch = globalThis.fetch const cookieMap = new Map<string, string>() function parseCookieString(cookieString: string): Record<string, string> { return cookieString.split('; ').reduce( (acc, cookie) => { const [name, ...rest] = cookie.split('=') acc[name] = rest.join('=') return acc }, {} as Record<string, string>, ) } function buildCookieString(cookies: Record<string, string>): string { return Object.entries(cookies) .map(([name, value]) => `${name}=${value}`) .join('; ') } // A wrapper around fetch since RN messes up handling of cookies export function fetch(input: RequestInfo | URL, init?: RequestInit | undefined) { const hostname = new URL(input instanceof Request ? input.url : input).hostname return origFetch(input, { ...init, headers: { ...(init?.headers || {}), Cookie: cookieMap.get(hostname) || '', }, credentials: 'omit', // Omit cookies and handle ourselves }).then(res => { const existingCookies = cookieMap.get(hostname) || '' const existingCookiesObj = parseCookieString(existingCookies) const newCookies = setCookieParser.parse(res.headers.get('Set-Cookie') || '', { map: true, // Use map to get an object with cookie names as keys }) // Update the existing cookies with new ones for (const [name, cookie] of Object.entries(newCookies)) { existingCookiesObj[name] = cookie.value } cookieMap.set(hostname, buildCookieString(existingCookiesObj)) return res }) }
您可以导入并使用它,或者覆盖 fetch (

global.fetch = fetch

)


-1
投票
我也遇到了同样的问题,最后不得不使用 AsyncStorage 来保存令牌和 cookie,并使用react-native-cookies 来清除所有 cookie。例如:CookieManager.cearAll()

© www.soinside.com 2019 - 2024. All rights reserved.