「缓存知识」HTTP缓存

364 阅读3分钟

HTTP 缓存

HTTP中的缓存分为强缓存和协商缓存两种。缓存的主要目的是减少对服务端的重复请求,减少网络负载。HTTP的缓存流程如下: image.png

1. 强缓存

强缓存顾名思义它比较强(狗头),因此如果命中强缓存,浏览器就不需要发送请求到服务端来请求资源,直接读取浏览器本地缓存。

在 Chrome 中,强缓存又分为 Disk Cache (存放在硬盘中)和 Memory Cache (存放在内存中),存放的位置是由浏览器控制的。

是否命中强缓存由以下三个字段来控制,优先级从上往下递增

  1. Expires(deprecated after Http1.1)
  2. Cache-Control
  3. Pragma

Expires

当我们第一次请求某个资源的时候,服务端的响应头内会携带一个Expires字段,它用来表示资源的过期时间。

因此下次请求的时候,只需判断资源是否过期来决定是否向服务器发送请求。

例如: Expires: Wed, 22 Nov 2019 08:41:00 GMT

但是Exprires是根据服务端的时间来作为标准,但是比较的时候是和客户端的时间进行比较,因此会有概率误判,这个方法在HTTP/1.1被废弃了。

Cache-Control

在HTTP1.1中,采用了一个另外一个字段:Cache-Control。这个字段也是存在于服务器返回的响应头中。

它和Expires本质的不同在于它并没有采用“具体的过期时间点” ,而是采用过期时长来控制缓存。对应的字段是max-age

比如:Cache-Control:max-age=3600,表示3600秒内可直接使用缓存。

Cache-Control还有其他的一些字段,如no-cache、no-store、must-revalidate等会触发缓存验证。

Pragma

PragmaHTTP/1.0 标准中定义的一个 header 属性,请求中包含 Pragma 的效果跟在头信息中定义 Cache-Control: no-cache 相同,但是 HTTP 的响应头没有明确定义这个属性,所以它不能拿来完全替代 HTTP/1.1 中定义的 Cache-control 头。通常定义 Pragma 以向后兼容基于 HTTP/1.0 的客户端。Pragma只有一个值:no-cache,代表禁用强缓存。

Pragma: no-cache

2. 协商缓存

使用协商缓存有以下两个条件:

  1. 强缓存失效的或者请求头中设置了禁用强缓存(如设置了Pragma或者Cache-Control设置了no-cache、no-store等)
  2. 上一次的资源请求有返回Etag或者Last-Modified字段,并且用于这一次的请求,并且服务端返回304

ETag/If-None-Match

当我们请求某个资源的时候,响应头内会携带一个Etag字段,它的值是一串Hash随机字符串,它用来表示一个资源的唯一标识

我们用上一次获取来的ETag的值,来作为这一次请求头中If-None-Match字段的值,那么服务端会用这个(过去文件的)唯一标识来和将要返回的资源的唯一标识做一个比较,如果相等的话,则返回304,并加载浏览器缓存;如果不相等,则返回新资源200。

此外ETag还有强弱之分,这里不展开细说。

Last-Modified/If-Modified-Since

当我们请求某个资源的时候,响应头内会携带一个Last-Modified字段,它用来表示一个资源的最后修改时间

我们用上一次获取来的Last-Modified的值,来作为这一次请求头中If-Modified-Since字段的值,那么服务端根据文件最后一次修改时间和 If-Modified-Since 的值进行比较,如果相等,返回 304 ,并加载浏览器缓存;如果不相等,则返回新资源200。