【问题标题】:Caching responses based on date and age headers基于日期和年龄标头缓存响应
【发布时间】:2021-04-21 11:08:30
【问题描述】:

我们看到一些行为,我们没有在 OkHttp 中缓存响应,并最终每次都访问服务器。但是,响应在未来有一个 Expires 时间,所以理想情况下它会被缓存。

这是我们在响应中看到的标头的一个简单示例(请求已发送,响应已在 Sat, 16 Jan 2021 00:40:36 GMT 接收):

date: Sat, 16 Jan 2021 00:40:36 GMT
age: 6
expires: Sat, 16 Jan 2021 00:40:40 GMT
last-modified: Sat, 16 Jan 2021 00:40:30 GMT

根据我从 CacheStrategy 中看到的情况,问题在于它将日期 + 年龄相加,以查看它是否超过了到期时间。在这种情况下,00:40:36 + 6 = 00:40:42 > 00:40:40,所以它最终不会被添加到缓存中。

所以我认为理想情况下,响应日期将等于最后修改日期(在本例中为 2021 年 1 月 16 日星期六 00:40:30 GMT),或者我们需要有一个自定义 CacheStrategy 才能使用 last-修改而不是这些计算的日期。

如果有人对我是否做出任何错误假设有任何见解,或者上述选项之一是否更可取,请告诉我。我查看了日期/年龄标题的一些规范,我有点不清楚在这种情况下它们应该是什么。

我还发现调试 OkHttp 中的缓存行为有点困难,现在我一直在使用条件断点来尝试跟踪它,但如果有人有更好的想法,我也会很感激.

【问题讨论】:

  • 您是否考虑过使用网络拦截器将合成缓存标头添加到响应中?或者考虑向请求添加一个 max-stale 缓存控制标头。
  • 考虑包括缓存日志输出。 square.github.io/okhttp/caching square.github.io/okhttp/events 您可以显示缓存事件,或输出缓存对象类型或相关的原始标头。我想了解那里是否缺少一些可以更容易推理的东西。
  • 就标头而言,我们不会在请求中发送任何缓存控制标头,我们会发送一个 etag,但理想情况下,如果之前的响应仍然存在,我们甚至不会访问网络有效的。除了我示例中的 4 个标头之外,我们在响应中返回的唯一其他相关标头是 cache-control: public, stale-while-revalidate=1, stale-if-error=86400
  • 在我们的请求中发送额外的缓存控制标头并不理想;在我们的例子中,我们实际上想要全天不同级别的缓存。因此,同一端点可能会返回有效期为 2 小时的响应,但稍后会返回仅有效期为 10 秒的响应。理想情况下,这是由服务器驱动的。我们尝试使用网络拦截器从响应中删除 age 标头,这似乎以我们期望的方式缓存,但如果是这样的话,我很惊讶发现关于这个主题的讨论很少
  • 对我们来说,当我们用我们的请求访问 cloudflare 时,就会出现这个问题。基本上,cloudflare 缓存来自源服务器的响应,在响应中附加 age 标头,但似乎总是用当前时间覆盖 date 标头。如果我们跳过 cloudflare 并直接访问我们的源服务器,缓存似乎按我们预期的方式工作。但是,是的,我不是 HTTP 协议方面的专家,所以我不确定这是否是 cloudflare 或 okhttp 的问题,或者我们是否需要为其添加自定义逻辑(例如,通过删除年龄标头,或者添加响应中缓存控件的 max-age

标签: android http-headers okhttp cloudflare cache-control


【解决方案1】:

用设置 max-age 指令的 Cache-Control 标头替换 expires 标头:

Cache-Control: max-age=86400

这将导致 OkHttp 将响应缓存 24 小时,无论响应何时提供。 expires 标头有问题,因为 CloudFlare 将其视为特定的过期时间,而不是持续时间。

【讨论】:

    【解决方案2】:

    我建议尝试使用带有您选择的max-age 的“Cache-Control”标头。

    我这样做的主要原因是因为官方文档中的示例也显示了这一点,请参阅:https://square.github.io/okhttp/interceptors/#rewriting-responses

    .header("Cache-Control", "max-age=60")

    这样做的首选方式显然是在后端。 如果您无法修改后端,那么我想拦截器将是第二种选择。 请注意,这是不鼓励使用的最后一个选项。

    除了你的后端,我还要看看 cloudflare 本身提供的选项:https://support.cloudflare.com/hc/en-us/articles/360021806811-Getting-Started-with-Cloudflare-Caching

    【讨论】:

    • 另请注意,OkHttp3 缓存可能不适用于 POST 请求(参见:stackoverflow.com/a/42547537/1688441
    猜你喜欢
    • 2020-06-01
    • 1970-01-01
    • 2013-10-06
    • 1970-01-01
    • 2021-07-12
    • 2015-11-08
    • 1970-01-01
    • 2021-09-05
    • 2019-01-25
    相关资源
    最近更新 更多