如何影响 OkHttp 缓存的使用?

Posted

技术标签:

【中文标题】如何影响 OkHttp 缓存的使用?【英文标题】:How to influence OkHttp cache usage? 【发布时间】:2021-12-30 12:58:57 【问题描述】:

您可以将缓存添加到 OkHttpClient,这将根据各种与缓存相关的 HTTP 标头(如 cache-control)工作:

val okHttpClient =
    OkHttpClient.Builder().apply 
        cache(Cache(File("http_cache"), 50 * 1024 * 1024))
    .build()  

服务器(不受我控制)在响应中指定了cache-control: no-cache 的资源。但无论如何我都想缓存它,因为我知道在某些情况下这样做是安全的。

我想我可以拦截响应并相应地设置标题:

val okHttpClient =
    OkHttpClient.Builder().apply 
        cache(Cache(File("http_cache"), 50 * 1024 * 1024))
        addInterceptor  chain ->
            val response = chain.proceed(chain.request())
            response
                .newBuilder()
                .header("cache-control", "max-age=1000") // Enable caching
                .removeHeader("pragma")  // Remove any headers that might conflict with caching
                .removeHeader("expires") // ...
                .removeHeader("x-cache") // ...
                .build()
        
    .build()

很遗憾,这不起作用。显然,缓存决策是在拦截器拦截之前做出的。使用addNetworkInterceptor() 代替addInterceptor() 也不起作用。

相反 - 当服务器通过设置 cache-control: no-cache 允许缓存时禁用缓存 - 也不起作用。

编辑:

Yuri's answer 是正确的。 addNetworkInterceptor().header("Cache-Control", "public, max-age=1000") 有效,.header("cache-control", "max-age=1000") 也有效。

但是在进行实验时,我做了一些错误的假设。这是我后来发现的:

OkHttp 缓存根本不缓存 POST 请求的响应。 (Source) "请注意,no-cache 并不意味着“不缓存”。no-cache 允许缓存存储响应,但要求它们在重用之前重新验证它。如果您认为“不缓存”的意义want 实际上是“不存储”,然后no-store 是要使用的指令。” (Source)

【问题讨论】:

【参考方案1】:

它需要是一个networkInterceptor,但它确实有效。

试试.header("Cache-Control", "public, max-age=1000"),它应该缓存15分钟。

见https://***.com/a/23503804/1542667

【讨论】:

谢谢。我已经相应地更新了我的问题。

以上是关于如何影响 OkHttp 缓存的使用?的主要内容,如果未能解决你的问题,请参考以下文章

离线时使用 OKHttp 进行改造如何使用缓存数据

如何更改 Okhttp 中的默认缓存策略?

如何使用 Retrofit 和 OKHttp 在下一次请求时使缓存路由无效/强制更新?

使用OkHttp拦截器和Retrofit进行缓存

使用OkHttp拦截器和Retrofit进行缓存

OKHttp缓存有效期