1. 1. 强缓存
    1. 1.1. Expires
    2. 1.2. Cache-Control
  2. 2. 协商缓存
    1. 2.1. Last-Modify/If-Modify-Since
    2. 2.2. ETag/If-None-Match
  3. 3. 整体流程图
  4. 4. 几种状态码的区别
    1. 4.1. 缓存存储位置:
浏览器缓存机制:强缓存、协商缓存

浏览器缓存(Brower Caching)是浏览器在本地磁盘对用户最近请求过的文档进行存储,当访问者再次访问同一页面时,浏览器就可以直接从本地磁盘加载文档。

浏览器缓存的优点有:

  • 减少了冗余的数据传输,节省了网费
  • 减少了服务器的负担,大大提升了网站的性能
  • 加快了客户端加载网页的速度

浏览器缓存主要有两类:协商缓存和强缓存

浏览器在第一次请求发生后,再次请求时:

  1. 浏览器会先获取该资源缓存的 header 信息,根据其中的 expires 和 cache-control 判断是否命中强缓存,若命中则直接从缓存中获取资源,包括缓存的 header 信息,本次请求不会与服务器进行通信;

  2. 如果没有命中强缓存,浏览器会发送请求到服务器,该请求会携带第一次请求返回的有关缓存的 header 字段信息(Last-Modified/IF-Modified-Since、Etag/IF-None-Match),由服务器根据请求中的相关 header 信息来对比结果是否命中协商缓存,若命中,则服务器返回新的响应 header 信息更新缓存中的对应 header 信息,但是并不返回资源内容,它会告知浏览器可以直接从缓存获取;否则返回最新的资源内容

强缓存

Expires

Expires 是 http1.0 提出的一个表示资源过期时间的 header,它描述的是一个绝对时间,由服务器返回。

Expires 受限于本地时间,如果修改了本地时间,可能会造成缓存失效。

1
Expires: Wed, 11 May 2018 07:20:00 GMT

Cache-Control

Cache-Control 出现于 HTTP / 1.1,优先级高于 Expires ,表示的是相对时间。

1
Cache-Control: max-age=315360000

Cache-Control 的常见其他配置字段:

  • no-cache:使用缓存协商,根据服务的协商返回情况看是否使用本地缓存。

  • no-store:直接禁止游览器缓存数据,每次用户请求该资源,都会向服务器发送一个请求,每次都会下载完整的资源。

  • public:可以被所有的用户缓存,包括终端用户和 CDN 等中间代理服务器。

  • private:只能被终端用户的浏览器缓存,不允许 CDN 等中继缓存服务器对其缓存。

协商缓存

当浏览器对某个资源的请求没有命中强缓存,就会发一个请求到服务器,验证协商缓存是否命中,如果协商缓存命中,请求响应返回的 http 状态为 304 并且会显示一个 Not Modified 的字符串。

协商缓存是利用的是【Last-Modified,If-Modified-Since】【ETag、If-None-Match】这两对 Header 来管理的。

Last-Modify/If-Modify-Since

Last-Modified 表示本地文件最后修改日期,浏览器会在 request header 加上If-Modified-Since(上次返回的Last-Modified的值),询问服务器在该日期后资源是否有更新,有更新的话就会将新的资源发送回来。

1
Last-Modify: Thu,31 Dec 2037 23:59:59 GMT

但是如果在本地打开缓存文件,就会造成Last-Modified被修改,所以在 HTTP / 1.1 出现了ETag

ETag/If-None-Match

Etag就像一个指纹,资源变化都会导致 ETag 变化,跟最后修改时间没有关系,ETag可以保证每一个资源是唯一的。

If-None-Match的 header 会将上次返回的Etag发送给服务器,询问该资源的Etag是否有更新,有变动就会发送新的资源回来。

具体为什么要用ETag,主要出于下面几种情况考虑:

你可能会觉得使用 Last-Modified 已经足以让浏览器知道本地的缓存副本是否足够新,为什么还需要 Etag 呢?HTTP1.1 中 Etag 的出现主要是为了解决几个 Last-Modified 比较难解决的问题:

  1. 一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新 GET;

  2. 某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说 1s 内修改了 N 次),If-Modified-Since 能检查到的粒度是 s 级的,这种修改无法判断(或者说 UNIX 记录 MTIME 只能精确到秒);

  3. 某些服务器不能精确的得到文件的最后修改时间。

Last-Modified 与 ETag 是可以一起使用的,服务器会优先验证 ETag,一致的情况下,才会继续比对 Last-Modified,最后才决定是否返回 304。

整体流程图

672fb4ce-28f9-498d-9140-b3ff9f47d62f

几种状态码的区别

  • 200:强缓 Expires/Cache-Control 存失效时,返回新的资源文件

  • 200(from disk/memory cache):强缓 Expires/Cache-Control 两者都存在,未过期,Cache-Control 优先 Expires 时,浏览器从本地获取资源成功

  • 304(Not Modified):协商缓存 Last-modified/Etag 没有过期时,服务端返回状态码 304

缓存存储位置:

内存缓存(memory cache)和硬盘缓存(disk cache)

区别 内存缓存 硬盘缓存
存储内容 JS,字体,图片等 CSS 等
读取速度
时效性 进程关闭则清空 可以缓存较长时间
空间 空间小 空间大