使用“If-None-Match”获取:“etag”标头在 React Native 应用程序中始终返回 200

Posted

技术标签:

【中文标题】使用“If-None-Match”获取:“etag”标头在 React Native 应用程序中始终返回 200【英文标题】:Fetch with 'If-None-Match': "etag" header always returning 200 in React Native app 【发布时间】:2020-01-06 18:01:17 【问题描述】:

我在 React Native 应用程序中遇到了一个非常奇怪的问题,其中带有 etag 的简单提取总是返回 200 而不是预期的 304

const response = await fetch(url, 
  method: 'GET',
  headers: 
    'If-None-Match': etag
  ,
);

其中etag 类似于"33a64df551425fcc55e4d42a148795d9f25f89d4"

当我直接通过 Postman/Insomnia 之类的方式提出此请求时,它正在工作,并且我得到了适当的 304 响应。

在 Reactotron 中检查应用程序,我可以看到网络请求标头似乎是正确的:

如果我将 JSON 请求复制为 cURL,我会得到以下信息:

curl -H "if-none-match:"33a64df551425fcc55e4d42a148795d9f25f89d4"" https://url/to/api

稍作修改以仅显示标题:

curl -sD - -o /dev/null -H "if-none-match:"33a64df551425fcc55e4d42a148795d9f25f89d4"" https://url/to/api

它也只返回一个200,但如果我像这样转义 etag 周围的引号,它可以工作:

curl -sD - -o /dev/null -H "if-none-match:\"33a64df551425fcc55e4d42a148795d9f25f89d4\"" https://url/to/api

我真的很困惑,因为我尝试了以下所有变体:

'If-None-Match': etag
'If-None-Match': `"$etag"`
'If-None-Match': `\"$etag\"`
'If-None-Match': '"' + etag + '"'

无济于事,我做错了什么?

将相同的 fetch 请求放入 html 文件并在浏览器中进行测试以达到预期的304 状态。

【问题讨论】:

【参考方案1】:

我在 React Native App 上使用 Axios 时遇到了同样的问题。我还尝试了相反的“If-Match”并得到 200,所以好像标题甚至不存在。

const query = 
  method: 'GET',
  url: `someurl`,
  headers: 
    Authorization: `Bearer $token`,
    'If-Match': etag,
  ,
;

let response = await axios(query);

【讨论】:

【参考方案2】:

在底层,React Native 使用的是 NSURLCache,即使它从上游接收到 304,它也会返回 200,至少从我在线阅读的内容来看是这样。使用 Charles Web Proxy 或 App Store 中的其他此类代理查看一下,您将在网络流量到达您的应用程序之前看到它。谷歌搜索还揭示了很多关于缓存的边缘情况,例如默认情况下显然不缓存私有响应。

【讨论】:

以上是关于使用“If-None-Match”获取:“etag”标头在 React Native 应用程序中始终返回 200的主要内容,如果未能解决你的问题,请参考以下文章

ETag 和 If-None-Match HTTP 标头不起作用

Last-Modified If-Modified-Since ETag If-None-Match

批量删除联系人时出现“If-Match or If-None-Match header or entry etag attribute required”错误

If-None-Match 有效时 304 Not Modified

爱创课堂每日一题第二十四天-ETag应用?

If-None-Match标头未接受请求标头