提问者:小点点

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


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

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

    React Native有现成的组件来做这些事情吗?如果不是,人们最常用的处理方式是什么?


共3个答案

匿名用户

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响应中的Cache-Control和Expires头。每个库都有自己的配置,您可以进行调整,例如控制缓存大小或禁用缓存。

还有这个:如何使用NSURLSession来确定资源是否发生了变化?

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

如果缓存的响应已过期,则NSURLSession将向源服务器发送一个新请求,但将在缓存(虽然已过期)结果中使用Last Modified和Etag实体头,包括If Modified-Since和If None Match头;这种行为是内置的,除了启用缓存之外,您不必做任何事情。如果源服务器返回304(未修改),则NSURLSession会将其转换为应用程序的200响应(使其看起来像是您获取了资源的新副本,即使它仍然是从缓存中提供的)。

匿名用户

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

我刚刚发现了这个,因为我想看看是否有人在React中做过这个,更不用说React Native了,我什么也没看到。

小鬼,是时候卷起袖子发明这个东西了。。。

匿名用户

好的,这是我当前的解决方案,尚未进行生产测试。会喜欢你的谷歌反馈。

我使用Axios,但如果你不这样做,你仍然会围绕你周围的任何包装器来实现这个 - 除非你使用原生获取!

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与请求一起发送。

我们可以升级它以记住正确的状态代码,或者将etags保存到磁盘,杜诺。你怎么想:)?