Http Cache-Control 缓存策略问题,什么情况下设置 no-cache 会使得资源请求返回 200 (disk cache)?

查看 108|回复 14
作者:Albertcord   
表现出来是问题所述,我这里讲下复现(人工复现)路径:
我将系统部署回老版本 1.1.0 ,然后同事访问系统(为 1.1.0 ),我再部署新版本 1.2.0 ,同事 F5 刷新页面,访问系统。前端架构是用的微前端(老版本用的 micro-app ,新版本用的 qiankun ),获取子应用当然是微前端沙箱的 fetch (但是我理解这里都是没有影响的)。
重点来了:同事机器访问 1.1.0 后就相当于缓存住了,之后访问 1.2.0 ,子应用的资源是 fetch 200 ,disk-cache ,然后请求头只有 Referer, User-Agent ,响应头里有 Cache-Control no-cache Last-Modified, Etag ,也就是 1.1.0 版本的子应用 entry (老的 html )
我本机无法复现,查看 nginx 日志,确实同事机器是只在访问 1.1.0 的时候打到日志,后面都是走的本机缓存,我无法理解的是为什么 no-cache 会表现出强缓存的现象?
我现在解决是先改了 html 策略为 no-store (而且吊诡的是,nginx 配置加了之后除了 Cache-Control no-cache 这一行,还多了一行 no-store ,难以理解),然后子应用访问时加时间戳(主要解决问题是这个方式,其实标题问题没有解决)
我现在猜测是第一次访问时,不知道哪里的中间代理(中间人)加了强缓存(但是响应头的 Last Modified Etag 又是哪里来的?),或者用的东方通有什么 bug ?(但配置文件跟 nginx 一样的)
测试浏览器都是 Chrome ,本机是最新 110 版本的,复现同事版本分别是 122 (最新)、96
想问问社区大佬原因或者排查思路?赐教
Epiloguess   
从客户端的角度上来说,如果服务端配置了 no-cache,对于客户端的非首次请求,headers 里应该有 if-none-match.
如果没有的话,有两种可能
1.服务端一开始没有配置 no-cache,客户端缓存了内容,服务器此时配置 no-cache 是无效的,但客户端不应该收到 no-cache 的响应头
2.客户端没有发送`if-none-match`的能力,导致虽然配置了 no-cache,但是只能用`last-modified`作为 fallback,这种情况虽然少见,但是确实可能存在
OP 可能需要清空客户端的缓存,再做几组测试
Albertcord
OP
  
@epiloguess 第二种,如果使用 last-modified 作为 fallback ,也应该是 304 状态码
我其实最难接受跟理解的就是这个 200 状态码然后走了 disk cache ,这个请求都不跟 nginx 服务作缓存的协商验证是否过期
难受的是我本机复现不了,复现的了的同事没空配合我测试
tool2dx   
@Albertcord 200 是假的,是 disk cache 返回的,又不是服务器返回的。
在 Expires 和 max-age 都没有过期的情况下,浏览器不会发送新的网络请求,哪怕是 304 也不会主动去获取。所以资源才需要加 hash 名字。
Epiloguess   
@Albertcord `last-modified`也被用作浏览器的启发式缓存,不一定要返回 304 的,浏览器认为资源没过期直接从 disk cache 中返回了,状态码 200
Albertcord
OP
  
@epiloguess 这个有文档来源吗?颠覆了以往知识- -
Albertcord
OP
  
@tool2dx 可是我确认本机没有发 max-age or Expires
Epiloguess   
@Albertcord Last-Modified is also used by crawlers to adjust crawl frequency, by browsers in heuristic caching, and by content management systems (CMS) to display the time the content was last modified.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Last-Modified
也就是说,除了 If-Modified-Since 或 If-Unmodified-Since 会用到这个字段,其他地方也会用到这个字段
JK9993   
@Albertcord #6 没有设置的话浏览器会给一个默认的值
Albertcord
OP
  
@epiloguess 看起来确实是这个原因,那就是 nginx 配置的 no-cache 其实没有挂上去,又有默认的 Last-Modified ,导致了启发式缓存
您需要登录后才可以回帖 登录 | 立即注册

返回顶部