天天看点

HTTP缓存机制:强缓存与协商缓存

HTTP缓存分为两种,强缓存与协商缓存,先来看几张HTTP请求的截图:

HTTP缓存机制:强缓存与协商缓存
HTTP缓存机制:强缓存与协商缓存
HTTP缓存机制:强缓存与协商缓存
HTTP缓存机制:强缓存与协商缓存
HTTP缓存机制:强缓存与协商缓存

可以发现请求头/响应头里一些有意思的属性:ETag、Last-Modified、Expires、Cache-Control、Pragma、If-None-Match、If-Modified-Since等,这些都与HTTP缓存有关系

强缓存

Expires / Cache-Control

Expires是HTTP1.0中的强缓存机制,是一个绝对值时间。

Cache-Control是HTTP/1.1中出现的强缓存机制,是一个相对值时间。

所以当两者同时出现时,以Cache-Control优先。因为Expires是绝对值时间,客户端与服务端时间可能存在误差,所以相对于Cache-Control来说,Expires准确率没那么高。

当浏览器第一次去服务器请求数据时,服务器返回数据,响应头Date属性有此请求的时间 Mon, 22 Mar 2021 06:17:00 GMT

若服务器希望此次HTTP缓存30秒有效,则响应头中可如下设置

Expires:Mon, 22 Mar 2021 06:17:30 GMT

Cache-Control:max-age=30

当浏览器再次发起请求,浏览器通过检查本地缓存的数据,若未过期,则不需向服务器发起请求,直接使用本地的缓存数据,此时HTTP状态码为200(from memory cache / from disk cache)从内存中读取数据或从硬盘中读取数据

HTTP缓存机制:强缓存与协商缓存

cache-control的其他属性:https://baike.baidu.com/item/Cache-control/1885913

Pragma

Pragma是HTTP/1.0中的缓存机制,用来向后兼容,算是时代的旧产物,快被抛弃了。

Pragma:no-cache 与 cache-control:no-cache  作用相同

当两者同时出现时,Pragma优先级更高

协商缓存

协商缓存通常一对一对配合使用,ETag与If-None-Match是一对,Last-Modified与If-Modified-Since是一对。

ETag / If-None-Match

当浏览器第一次进行请求时,响应头返回ETag标识资源的唯一值(当资源发送变化,这个值会变)

当浏览器再次进行请求,强缓存又没有命中的情况,浏览器会向服务器发起请求,并在请求头中携带上次请求缓存的ETag值,放在If-None-Match中。

例如第一次请求,响应头返回

ETag:48472445140208031

再次请求,强缓存没有命中,则发起请求的请求头携带

If-None-Match:48472445140208031

服务端根据请求的If-None-Match判断是否命中缓存,如果资源没有变化,则值相同,返回HTTP状态 304,浏览器从本地缓存中取值。如果资源被修改,etag值发生变化,则返回HTTP状态码200,新的资源和新的ETag值

Last-Modified / If-Modified-Since

这对协商缓存情侣与上对相比,是通过资源的最后一次修改时间来判断缓存是否命中。

有以下两个缺点:

  • 只要编辑了,不管内容是否真的有改变,都会以这最后修改的时间作为判断依据,当成新资源返回,从而导致了没必要的请求响应,而这正是缓存本来的作用即避免没必要的请求。
  • 时间的精确度只能到秒,如果在一秒内的修改是检测不到更新的,仍会告知浏览器使用旧的缓存。

请求过程与上对情侣类似。如果两对协商缓存情侣同时存在,以ETag优先进行比对