http缓存的那些事儿

缓存头详细解释

Cache-Control

Cache-Control 是HTTP / 1.1通用头字段被用于为请求和响应缓存机制指定指令。
使用此标头可通过其提供的各种指令来定义缓存策略。

没有缓存 no-store

缓存不应存储有关客户端请求或服务器响应的任何内容。一个请求被发送到服务器,并且每次都下载一个完整的响应。

Cache-Control: no-store

缓存但重新验证 no-cache

缓存将在释放缓存副本之前将请求发送到原始服务器进行验证。

Cache-Control: no-cache
  • 强制请求服务器验证是否需要缓存
  • 若指定no-cache,强制浏览器(User Agent)必须先请求服务器验证新鲜度,待服务器那边确认新鲜后,决定使用使用缓存否,304使用,200覆盖缓存。 (不管该缓存是否新鲜,都先请求服务器,服务器304状态时,使用缓存,此时服务器不返回具体内容)
  • must-revalidate

若指定must-revalidate,则浏览器会首先等待文档过期,然后才去请求服务器验证新鲜度
(过期之前直接使用本地缓存,不与服务器交互)

私人和公共缓存 private|public

"public"指令指示响应可以被任何缓存器缓存。如果具有HTTP身份验证或响应状态代码的页面通常不可缓存,则现在应该对其进行缓存,这很有用。
"private"表示响应仅针对单个用户,并且不得由共享缓存存储。在这种情况下,专用浏览器缓存可以存储响应。

Cache-Control: private
Cache-Control: public

期满 max-age=

这里最重要的指令是"max-age=",这是资源被视为新鲜的最长时间。与Expires相反,此指令是相对于请求时间的。对于应用程序中不会更改的文件,通常可以添加主动缓存。
例如,这包括静态文件,例如图像,CSS文件和JavaScript文件。
有关更多详细信息,请参见下面的"新鲜度"部分。

Cache-Control: max-age=31536000

验证方式

使用"must-revalidate"指令时,缓存必须在使用之前验证过时资源的状态,并且不应使用过期的资源。
有关更多详细信息,请参见下面的"验证"部分。

Cache-Control: must-revalidate

Pragma

Pragma是HTTP / 1.0标头,未指定用于HTTP响应,因此,如果请求中省略了标头字段Cache-Control,尽管它的行为与相同,但它不是一般HTTP / 1.1 标头的可靠替代。使用仅适用于HTTP / 1.0客户端的向后兼容性。Cache-Control: no-cache Cache-Control Pragma

新鲜度

缓存时序图

新鲜度寿命是基于多个标头计算的。如果Cache-control: max-age=N指定了“ ”标头,则新鲜度寿命等于N。如果不存在此标头(通常是这种情况),则检查是否存在Expires标头。如果Expires存在标头,则其值减去Date标头的值将确定保鲜期。最后,如果两个标题都不存在,请查找Last-Modified标题。如果存在此标头,则高速缓存的新鲜度生存期等于Date标头的值减去标头的值Last-modified除以10。
到期时间的计算如下:

expirationTime = responseTime + freshnessLifetime - currentAge

responseTime根据浏览器收到响应的时间是哪里。

缓存验证

当达到缓存文档的到期时间时,将对其进行验证或再次获取。仅当服务器提供了强验证器或弱验证器时,才可以进行验证。

当用户按下重新加载按钮时,将触发重新验证。如果缓存的响应包含“ Cache-control: must-revalidate”标头,也会在正常浏览下触发。另一个因素是“首Advanced->Cache选项”面板中的缓存验证首选项。有一个选项可在每次加载文档时强制进行验证

电子标签

"ETag"响应报头对浏览器(User Agent)是不透明的,可以用作强验证值。浏览器(User Agent)不知道该字符串表示什么,并且无法预测其值。
若响应头带有"ETag",则客户端可以将在下次请时发送"If-None-Match"请求头,以来验证缓存的资源。

"Last-Modified" 响应头可以被用作弱验证器。它被认为是弱的,因为它只有1秒的分辨率。
若响应头带有"Last-Modified",则客户端可以将在下次请时发送"If-Modified-Since"请求头,以验证缓存的资源。

服务器收到验证请求头时,可以忽略验证请求,并使用normal响应(200 OK),也可以返回(正文为空)以指示浏览器使用其缓存的副本(304 Not Modified)。

后者的响应还可以用于更新缓存资源的到期时间的响应头。

PHP 常用写法

<?

$time = 1585089925;
$lastmod = gmdate('D, d M Y H:i:s \G\M\T', $time);
$etag = 'try-cache';


$ifmod = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? $_SERVER['HTTP_IF_MODIFIED_SINCE'] == $lastmod : null; 
$iftag = isset($_SERVER['HTTP_IF_NONE_MATCH']) ? $_SERVER['HTTP_IF_NONE_MATCH'] == $etag : null; 

if (($ifmod || $iftag) && ($ifmod !== false && $iftag !== false)) { 
    header('HTTP/1.0 304 Not Modified'); 
} else {
    header("Last-Modified: $lastmod"); 
    header("ETag: $etag");
}

print_r($_SERVER);

?>

Last-Modified

允许304缓存,客户端收到Last-Modified值后,一般会默认带自动带另外一个响应头date,
等到过期后,下次浏览器(User Agent)请求带上if-modified-since 和cache-control: max-age=0

RSP:

  • last-modified: Wed, 25 Mar 2020 20:06:29 GMT
  • date: Wed, 25 Mar 2020 20:32:34 GMT

Next REQ:

  • if-modified-since: Wed, 25 Mar 2020 20:06:29 GMT
  • cache-control: max-age=0

相关文章:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching
https://blog.csdn.net/mK0vouYv4BwgX190fSd/article/details/89880083

发表新评论