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

URLSession缓存未按官方文档预期工作 排查与方案咨询

根据官方文档说明,使用默认useProtocolCachePolicy缓存策略时,逻辑应如下:

  1. 若请求无对应缓存响应,URL加载系统会从源站拉取数据;
  2. 若存在缓存响应,且缓存未标注每次请求都需重新校验、同时缓存未过期(未超出有效期),URL加载系统直接返回缓存响应;
  3. 若缓存已过期或需要重新校验,URL加载系统会向源站发送HEAD请求确认资源是否变更:若资源已变更则从源站拉取新数据,未变更则返回本地缓存响应。

但实际测试结果与文档描述完全不符:即使响应已缓存也从未被使用,系统也从未发送过HEAD请求。

测试场景

测试请求的目标URL会返回固定不变的ETag与Last-Modified响应头,且已至少发起过一次请求,确认响应已完成缓存(可通过iOS模拟器中应用的缓存数据库验证)。

使用默认useProtocolCachePolicy策略

若初始化URLSession时所用URLSessionConfiguration的requestCachePolicy设为useProtocolCachePolicy,响应确实会被存入缓存(可在缓存DB中查到),但缓存从未被调用:重复请求同URL时始终会发起新的GET请求,且不会携带If-None-Match或If-Modified-Since请求头,服务器始终返回HTTP 200全量响应,本地缓存被完全忽略。

为每个URLRequest单独设置reloadRevalidatingCacheData策略

若为每一个URLRequest单独设置cachePolicy为reloadRevalidatingCacheData,缓存机制可正常生效:每次发起请求时,GET请求会携带If-None-Match(值为缓存响应的ETag)与If-Modified-Since(值为缓存响应的Last-Modified)请求头;因资源未变更,服务器返回304 Not Modified,系统将本地缓存响应返回给调用方。

仅在URLSessionConfiguration上设置reloadRevalidatingCacheData策略

若仅在URLSessionConfiguration上设置requestCachePolicy = .reloadRevalidatingCacheData(而非为每个URLRequest单独设置),应用启动后仅首次请求会携带缓存相关请求头并收到304 Not Modified响应,后续请求均为无缓存头的普通GET请求。

测试结论

其余缓存策略均为“仅使用缓存数据”或“完全不使用缓存”的变体,与本次测试场景无关。

测试中完全不存在URLSession如文档描述那样发送HEAD请求的场景,也从未出现过基于原响应的过期时间信息直接返回缓存、无需重校验的情况。

目前采用的临时方案是为每一个URLRequest设置cachePolicy = .reloadRevalidatingCacheData,以实现基础的本地缓存能力:因为304 Not Modified响应仅返回响应头、不返回响应体,可减少网络传输流量。

希望了解是否存在更优解决方案,或如何配置才能让URLSession按照官方文档描述的逻辑正常工作。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 19:39:18