说说HTTP缓存Cache-Control响应头

前言

除非特别说明,否则以下内容和结论均经过实际测试并验证,测试用的浏览器:Google Chrome 98.0.4758.102正式版。

例子

先看下响应头Cache-Control的一些常见用法。

第一种:Cache-Control:max-age=N

浏览器获取到资源内容后,将资源内容缓存在本地,缓存有效期是N秒。
若过期前再次访问资源,直接使用本地缓存;过期后再访问,则向服务器发请求,若服务器检查资源没有更新,则返回304状态码;如果有更新,则返回200状态码以及新的资源内容。同时浏览器延长本地资源的缓存有效期。

访问次数 服务器行为 浏览器行为
第一次访问 返回200状态码以及资源内容 将资源缓存在本地
过期前访问 直接使用本地缓存,不访问服务器
过期后访问 如果资源没更新,返回304状态码;如果有更新,返回200状态码和新的资源内容 如果是304状态码,则直接使用本地缓存,并延长本地缓存的有效期;如果是200状态码,则更新本地缓存内容
第二种:Cache-Control:no-cache

资源可以缓存在浏览器本地,但每次使用缓存前,都要跟服务器协商确认资源是否有更新。

访问次数 服务器行为 浏览器行为
第一次访问 返回200状态码以及资源内容 将资源缓存在本地
后续访问 如果资源没更新,返回304状态码;如果有更新,返回200状态码和新的资源内容 如果是304状态码,则直接使用本地缓存;如果是200状态码,则更新本地缓存内容

疑点:这种使用方式没有定义max-age字段,缓存是否存在有效期?

第三种:Cache-Control:no-store

禁用缓存。浏览器每次都要请求服务器,服务器每次都要返回200状态码以及资源内容。

第四种:Cache-Control:max-age=N,must-revalidate

浏览器获取到资源后,将资源缓存在本地,有效期是N秒。过期前再次访问,不再请求服务器,直接使用本地缓存;过期后则需请求服务器,验证资源是否有更新。

访问次数 服务器行为 浏览器行为
第一次访问 返回200状态码以及资源内容 将资源缓存在本地
过期前访问 直接使用本地缓存,不访问服务器
过期后访问 如果资源没更新,返回304状态码;如果有更新,返回200状态码和新的资源内容 如果是304状态码,则直接使用本地缓存,并延长本地缓存的有效期;如果是200状态码,则更新本地缓存内容

是不是已经看出来,这种方式的效果跟第一种是一模一样的?唯一的区别就是must-revalidate字段。
在我测试的过程中,确实是一模一样的,但网上资料说其实有加must-revalidate和没加是有区别的,大概是说:

在没加must-revalidate的情况下,如果服务器发生异常没有响应浏览器的请求,则浏览器会使用本地已过期的缓存;如果有加,则不会使用过期的缓存。

不过这种区别我没有去测试和验证。

其它问题

1)如果没有Cache-Control响应头,或者头里没有定义max-age字段,缓存的有效期是多久?
答:如果没有定义max-age,则判断是否有Expires响应头,如果有的话,则有效期为:

Expires响应头的时间 - Date响应头的时间

如果也没有Expires响应头,则再判断是否有Last-modified响应头,如果有的话,则有效期为:

(Date响应头的时间 - Last-modified响应头的时间) / 10

2)为什么资源的本地缓存没有过期,但我刷新页面时,在Chrome浏览器的开发者工具里看到仍然没有使用本地缓存?
答:如果在Chrome里直接访问需要被缓存的资源文件(假设是test.js)的话,在刷新页面时,浏览器会禁止使用本地缓存,并在请求服务器时自动加一个Cache-Control:max-age=0的请求头,至于为什么这么做目前我也没搞清楚。
一种解决方案是,不要直接访问test.js文件,而是改为访问一个html页面,然后在html里加载test.js,这样浏览器就会使用本地缓存。

资料参考

  1. https://stackoverflow.com/questions/18148884/difference-between-no-cache-and-must-revalidate
  2. https://stackoverflow.com/questions/14496694/whats-default-value-of-cache-control
  3. https://zhuanlan.zhihu.com/p/60357719
  4. https://webmasters.stackexchange.com/questions/111298/what-happens-if-you-dont-set-cache-control-header
  5. https://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html

你可能感兴趣的:(其它,缓存,http,Cache-Control)