如何自定义控制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
相关产品推荐
相关产品推荐

