在 React Native 应用程序中使用 ETag 缓存 JSON 响应



在React Native 应用程序中实现以下场景的最佳方法是什么?

  1. 向服务器发出HTTP请求,获取JSON响应和ETag标头。
  2. 保存此 JSON 响应的方式即使在用户重新启动应用后也会保留。
  3. 每当重复此 HTTP 请求时,请发送 If-None-Match 标头。
    1. 收到"未修改"响应时,请使用持久缓存中的版本。
    2. 当您收到"成功"响应(表示响应已更改)时,使持久缓存失效,保存新响应。

React Native 是否有一个组件可以开箱即用地做这些事情?如果没有,人们最常用的处理方式是什么?

React native 的 fetch() API 遵循 http 缓存规范,它提供了这个功能。当您点击 304 时,将在缓存中找到 200 旧响应并重复使用。

详:

https://github.com/heroku/react-refetch/issues/142

回答如下: https://stackoverflow.com/a/51905151

React Native 的 fetch API 桥接到 iOS 上的 NSURLSession 和 Android 上的 okhttp3。这两个库都严格遵循 HTTP 缓存规范。缓存行为主要取决于 HTTP 响应中的缓存控制和过期标头。这些库中的每一个都有自己的配置,您可以进行调整,例如控制缓存大小或禁用缓存。

以及:如何使用 NSURLSession 来确定资源是否已更改?

NSURLSession 通过 NSURLCache 提供的缓存是透明的,这意味着当您请求以前缓存的资源时,NSURLSession 将调用完成处理程序/委托,就像发生了 200 响应一样。

如果缓存的响应已过期,则 NSURLSession 将向源服务器发送新请求,但将在缓存(尽管已过期)结果中使用上次修改时间和 Etag 实体标头包含 If-Modified-Since 和 If-None-Match 标头;此行为是内置的,除了启用缓存之外,您无需执行任何操作。如果源服务器返回 304(未修改),则 NSURLSession 会将其转换为应用程序的 200 响应(使其看起来像您获取了资源的新副本,即使它仍然从缓存中提供)。

Oof.已经一年多了。我想你知道这是一个响亮的"不",对吧?您必须解析响应标头以获取 ETag 并将其存储在设备上(您没有使用浏览器),然后在从您选择的存储机制中检索标头后将其添加到后续请求中。

我之所以找到这个,是因为我想看看是否有人在 React 中这样做过,更不用说 React Native了,但我什么也没看到。

Whelp,是时候卷起袖子发明这个东西了......

好的,这是我当前的解决方案,尚未经过生产测试。 希望你的反馈谷歌员工。

我使用 Axios,但如果你不这样做,你仍然围绕你拥有的 fetch 包装器实现这一点 - 除非你使用本机获取!

import api from 'your api wrapper.js'
api.etags = new Set;
api.cache = new Set;
api.addRequestTransform(request => {
const etag = api.etags.get(request.url);
if (etag) {
request.headers['HTTP_IF_NONE_MATCH'] = etag;
}
})
// or whatever you use to wrap ur HTT
api.addResponseTransform(response =>{ 
if (
response.status === 304 &&
response.headers &&
response.headers.etag &&
api.cache.has(response.headers.etag)
) {
console.log('%cOVERRIDING 304', 'color:red;font-size:22px;');
response.status = 200;
response.data = api.cache.get(response.headers.etag);
} else if (response.ok && response.headers && response.headers.etag) {
api.cache.set(response.headers.etag, response.data);
api.etags.set(response.config.url, response.headers.etag);
}
});

我们在这里所做的是将响应结果保存到 API.cache 中,并将 ETAG 保存到 API.etag 中,然后我们每次都发送带有请求的 ETAG。

我们可以将其升级为记住正确的状态代码,或者将 ETAG 保存到磁盘 Duno。 你怎么看:)?

最新更新