You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何自定义控制OkHttp的缓存策略,覆盖服务端返回的缓存头配置

你可以为OkHttpClient添加缓存功能,它会根据cache-control等各类HTTP缓存相关头规则生效:

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") // 启用缓存
                .removeHeader("pragma")  // 移除所有可能与缓存逻辑冲突的头
                .removeHeader("expires") // ...
                .removeHeader("x-cache") // ...
                .build()
        }
    }.build()

但遗憾的是这个方案不生效。看起来缓存决策是在拦截器触发前就已经完成了。即使用addNetworkInterceptor()替换addInterceptor()也无法生效。
反过来,当服务端允许缓存时,想要通过设置cache-control: no-cache禁用缓存的操作同样不生效。


更新

Yuri的回答是正确的,使用addNetworkInterceptor()搭配.header("Cache-Control", "public, max-age=1000")可以生效,单独设置.header("cache-control", "max-age=1000")也可以生效。
之前测试不生效是因为我存在几个错误假设,后续梳理的正确结论如下:

  • OkHttp缓存完全不会缓存POST请求的响应。
  • 注意no-cache并不等于“不缓存”。no-cache允许缓存存储响应,但要求复用前必须重新校验有效性。如果你想要的“不缓存”是指完全不存储,则需要使用no-store指令。

内容的提问来源于stack exchange,提问作者Marco Eckstein

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 19:24:10