浏览器HTTP缓存机制

我们知道通过HTTP进行请求的时候是十分占用资源的,需要进行三次握手建立连接,而且对于大数据的加载是十分缓慢的。对于用户以及开发者来说,我们希望实现对于变动不大的数据进行缓存复用,提升数据加载速度,缓解服务器压力。

缓存机制

首先我们看下下面两种场景下的网络请求状态。

场景一:页面的前进后退场景

image.png

场景二:页面按F5刷新

image.png

我们来看下网络状态,大概可以分为下面几种状态。

  1. memory cache:内存缓存,存在浏览器的进程里面一般包括图片和js
  2. disk cache: 硬盘缓存,存在浏览器本地。
  3. 返回码304: 文件没有发生变化(服务端返回)
  4. 真正的网络请求:进行http网络请求,一般是缓存过期,或者没有缓存,或者不适用缓存等场景。

可以看出来,网络请求存在上述缓存状态,后面我们会解析这些缓存的逻辑和实现机制。

1.1 HTTP头信息

我们来看一下这些请求的请求头和响应头存在什么差异。

image.png
其中涉及到如下HTTP首部

  1. 通用头信息
字段 描述
Cache-Control 缓存控制,具体取值和作用参考下面表格
Pragma 另一种随报文传输的指示方式,并不专用于缓存,当该字段值为no-cache的时候,会客户端不要对该资源读缓存

Cache-Control取值范围

字段 描述
private 仅客户端可以缓存,代理层不可以访问
public 客户端和代理服务器都可缓存
max-age=xxx 缓存的内容将在 xxx 秒后失效
no-cache 需要使用对比缓存来验证缓存数据
no-store 所有内容都不会缓存,强制缓存,对比缓存都不会触发
  1. 请求头:
字段 描述
If-Match 比较ETag是否一致
If-None-Match 比较ETag是否不一致
If-Modified-Since 比较资源最后更新的时间是否一致
If-Unmodified-Since 比较资源最后更新的时间是否不一致
  1. 实体头信息:
字段 描述
ETag 资源的唯一标识信息,资源发生变化会生成新的
Expires 有效期时间,服务端返回的到期时间
Last-Modified 最后一次修改的时间

1.2 浏览器缓存逻辑

缓存整体逻辑如下:
image.png

  1. 第一步,先判断是否存在缓存,当存在缓存的时候,判断缓存是否过期。这里需要用到的是缓存响应头里面的Expires和Cache-Control。
    • 会优先读取Cache-Control的值,如果存在max-age,将用报文生成时间Date+max-age 和当前时间对比,参看是否过期。如果明确为no-cache,则会不使用缓存,直接请求网络。no-store网络请求结果不会存储在本地,不会产生缓存。
    • 如果上述Cache-Control值。比较Expires(HTTP1.0的遗留物)中的过期时间与当前时间。判断是否过期。
  2. 第二步,如果缓存没有过期,判断上一次缓存结果是否存在ETag和Last-Modified。如果没有直接进行HTTP请求,如果有则进入下一步。因为这两个值是用于服务器判断缓存是否可用(也就是服务端文件是否发生变化的)
  3. 第三步,请求头中携带If-None-Match(缓存实体ETag) 和 If-Modified-Since(缓存时间)。主要有以下判断逻辑:
    1. If-None-Match 携带的是缓存实体的Etag,到达服务端后,服务端首先会判断当前的ETag跟If-None-Match 是否匹配,如果匹配则返回304,浏览器则会读取硬盘缓存,并显示;如果不匹配,则将服务端的实体返回,并将新的ETag写入响应头。
    2. If-Modified-Since 值为缓存实体里面响应头的Last-Modified 字段,请求头携带这个值带到服务端,服务端会判断当前实体在这个时间后时候发生了变化,如果发生了变化,则将新的请求结果返回,否则返回304,浏览器会使用缓存。
  4. 如果上述缓存都没有命中,则需要将最新的实体结果通过网络返回浏览器,包括响应头信息。
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享