为何OkHttp会缓存带有expires: -1头的响应?请求异常咨询
OkHttp缓存
expires: -1响应的原因及解决方案 为什么OkHttp会缓存带expires: -1的响应?
首先明确HTTP协议里expires: -1的语义:它不是禁止缓存,而是告诉客户端「这个响应已过期,不能直接复用」,必须先向服务器发起条件验证请求,确认资源是否有更新。
OkHttp严格遵循HTTP规范,所以会把该响应存入本地缓存;后续发起同一请求时,会自动携带if-modified-since头(值取自首次响应的last-modified),向服务器验证资源状态。若服务器返回304(未修改),OkHttp就复用缓存内容。
新增请求头后仍返回304的问题根源
问题出在两个环节:
- OkHttp的缓存键判定逻辑:
OkHttp默认仅将请求的URL、请求方法,以及少数影响响应内容的头(如Accept、Accept-Encoding、Accept-Language)纳入缓存键计算。如果你新增的请求头不在这个默认列表里,OkHttp会判定两次请求属于同一缓存条目,因此仍携带if-modified-since发起验证。 - 服务器的304响应逻辑:
服务器收到带if-modified-since的请求时,若未将你新增的请求头视为资源变更的判断依据,即便请求头变化,也会认为资源未更新,直接返回304。
可行解决方案
针对该场景,你可以从以下方向处理:
- 让OkHttp区分两次请求的缓存键:
自定义OkHttp的缓存键逻辑,将新增的请求头纳入缓存键计算。可通过继承CacheInterceptor或配置相关规则,让OkHttp识别两次请求的差异。 - 强制跳过缓存验证:
在第二次请求中添加Cache-Control: no-cache头,或调用OkHttp的request.cacheControl(CacheControl.FORCE_NETWORK),强制OkHttp发起全新请求,不携带任何条件验证头。 - 调整服务器逻辑:
修改服务器的请求处理逻辑,将你新增的请求头作为资源内容的判断依据——当请求头变化时,即便last-modified未更新,也返回200和新响应内容,而非304。
内容的提问来源于stack exchange,提问作者Finlay James Pearson
相关产品推荐
相关产品推荐

