【问题标题】:Caching a JSON response using ETag in a React Native app在 React Native 应用程序中使用 ETag 缓存 JSON 响应
【发布时间】:2017-10-08 20:07:44
【问题描述】:

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

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

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

【问题讨论】:

    标签: http caching react-native etag


    【解决方案1】:

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

    还有这个:How to use NSURLSession to determine if resource has changed?

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

    如果缓存的响应已经过期,那么 NSURLSession 将向源服务器发送一个新的请求,但是会在缓存的(虽然已过期)结果;此行为是内置的,除了启用缓存之外,您无需执行任何操作。如果源服务器返回 304(未修改),则 NSURLSession 会将其转换为应用程序的 200 响应(使其看起来像是您获取了资源的新副本,即使它仍然是从缓存中提供的)。

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

        【解决方案3】:

        好的,这是我目前的解决方案,尚未经过生产测试。会喜欢你的反馈谷歌员工。

        我使用 Axios,但如果你不使用 fetch 的任何包装器来实现它 - 除非你使用本机 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 中,并将 etags 保存到 api.etag 中,然后我们每次发送 etag 和请求。

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

        【讨论】:

          猜你喜欢
          • 2013-12-24
          • 1970-01-01
          • 2021-02-02
          • 2015-02-21
          • 1970-01-01
          • 2020-03-25
          • 1970-01-01
          • 2021-11-10
          • 1970-01-01
          相关资源
          最近更新 更多