为何已在URLSession设置缓存策略,仍需为URLRequest配置以避免缓存?
一、Session与Request缓存策略的作用逻辑差异
- URLSession的缓存配置:属于全局默认规则,作用于该session发出的所有请求,但它是「兜底规则」——如果单个request指定了专属缓存策略,会直接覆盖session的默认设置。反过来,若session的缓存配置存在漏洞(比如
.ephemeralsession仅避免磁盘缓存,但会保留内存临时缓存),单个request的策略也可能被session的底层逻辑干扰。 - URLRequest的缓存策略:是针对单请求的精确控制,但它依赖session提供的缓存容器。比如仅把session的
urlCache设为nil,理论上应禁用缓存,但部分iOS版本的网络栈可能在request无明确强制策略时, fallback 到系统级共享缓存,导致旧数据依然被复用。
你遇到的单独配置无效的情况,核心原因是:.ephemeral session的内存缓存会留存到session释放,仅靠它无法彻底清除内存级缓存;仅设置request的.reloadIgnoringLocalAndRemoteCacheData,若session仍保留内存缓存容器,依然会优先返回旧数据。只有同时清空session的缓存容器(urlCache = nil)+ 给request强制设置忽略所有缓存的策略,才能切断所有缓存来源。
二、与你提到的其他因素的关联
1. 服务器(http-server)的影响
基础版http-server默认的缓存响应头配置可能存在问题:比如它会给JSON文件返回较长有效期的Cache-Control或Expires头,即使客户端设置了部分缓存策略,iOS网络栈可能优先尊重服务器的缓存指令。同时配置session和request的规则,相当于给客户端加上“双重保险”,完全忽略服务器的缓存头约束。
2. iOS 17的潜在变化
iOS 17对URLSession的缓存逻辑做了优化,比如调整了内存缓存的生命周期、共享缓存的访问规则。旧版本中urlCache = nil可直接禁用所有缓存,但iOS 17中部分场景下,系统会为无缓存容器的session临时分配内存缓存,此时必须配合request的强制刷新策略才能彻底绕过。
3. URL字符串与JSON内容类型
- URL字符串:若请求URL完全固定(比如每次都请求同一个
data.json),iOS网络栈会更倾向于复用缓存,仅靠单一配置无法彻底触发新请求; - JSON内容类型:JSON属于系统默认的可缓存内容,若服务器未返回
Cache-Control: no-cache或no-store,单独的session配置不足以覆盖默认缓存行为,需要request层面的精确控制。
三、总结
同时配置两者的核心原因是:session和request的缓存策略是协同作用的,session负责管控缓存容器的存在与否,request负责指定单请求是否强制绕过缓存。单独配置某一项,都可能因iOS网络栈的底层 fallback 逻辑、服务器缓存头、iOS版本特性等因素,导致缓存规则未被彻底执行。
内容的提问来源于stack exchange,提问作者CalebK

