我对 okhttp 中的缓存支持有疑问。这是一个复杂的问题,所以我将其分为两部分。
no-cache
请求的处理策略我注意到请求头
Cache-Control: no-cache
,或者okhttp称之为CacheControl.FORCE_NETWORK
,不会通过传递If-None-Match
或If-Modified-Since
头等来导致缓存的响应验证,而不是这样,它总是导致网络请求并读取响应正文。
这是 RFC 9111 所说的:
5.2.1.4。无缓存
无缓存请求指令表示客户端希望在源服务器上没有成功验证的情况下不使用存储的响应来满足请求。
我这里的关键是“没有成功验证”。也就是说,如果应用程序没有网络,则禁止返回缓存的响应,因为它无法被验证。但如果有网络连接并且服务器返回
304
,那么你可以从缓存中获取响应。
本文中还有指令的非正式描述(Mozilla 文档中提到)
无缓存的一个很好的用例几乎是任何动态 HTML 页面。想想新闻网站的主页:它不是实时的,也不包含任何敏感信息,但理想情况下我们希望页面始终显示最新的内容。我们可以使用cache-control: no-cache 来指示浏览器首先检查服务器,如果服务器没有任何更新可提供(304),那么让我们重用缓存的版本。如果服务器确实有一些更新的内容,它会响应 (200) 并发送更新的文件。
它说 “如果服务器没有任何更新可提供(304),让我们重用缓存的版本”。
从形式上来说,okhttp 中当前的实现与 RFC 并不矛盾,但在我看来,在验证成功后从缓存中获取响应会更有效,以节省流量。这似乎与当前的行为没有区别,唯一的区别是字节不会再次通过网络传输。
Cache-Control
值用于节省流量的用例?Cache-Control
在没有网络时使用缓存响应的指令最好有以下策略:尝试在源服务器上验证缓存的响应,如果服务器响应它仍然有效(304),则使用它,但如果没有网络,则可以使用缓存的响应回复。这将使在移动应用程序中实现离线支持变得更容易。
最适合此目的的指令是
stale-if-error
(RFC 5861 和相同的文章)。
stale-if-error Cache-Control 扩展指示当遇到错误时,可以使用缓存的过时响应来满足请求,而不管其他新鲜度信息如何。
stale-if-error
的支持吗?提前谢谢您!
这总是会导致网络请求并读取响应正文
我不相信情况是这样。 OkHttp 将接受 304 并返回缓存的响应正文。您可以通过查看条件命中的cacheResponse 和networkResponse 字段来看到这一点。