Http缓存

Q:什么是缓存?

缓存是一种保存资源副本并在下次请求时直接使用该副本的技术,当 web 缓存发现请求的资源已经被存储,它会拦截请求,返回该资源的拷贝,而不会去源服务器重新下载。

一个优秀的缓存策略可以缩短网页请求资源的距离,减少延迟,节省网络流量,并且由于缓存文件可以重复利用,降低网络负荷,提高客户端响应。

刷新操作

  • 输入url跳转,前进后退
    • (强制缓存有效,协商缓存有效)
  • 手动刷新:F5
    • (强制缓存失效,协商缓存有效)
  • 强制刷新:command+shift+R(Mac)、Ctl+F5(Windows)
    • (强制缓存失效,协商缓存失效)

Http缓存

HTTP 缓存主要是通过请求和响应报文头中的对应 Header 信息,来控制缓存的策略。响应头中相关字段ExpiresCache-ControlLast-ModifiedEtag应用于不同的缓存策略。

以下根据是否需要重新向服务器发起请求来分类介绍以下两种缓存:强制缓存协商缓存

用到的Http状态码

200:表示资源获取成功

304:表示资源没发生改变

强制缓存

  • 当客户端第二次向服务器请求相同的资源时,不会向服务器发送请求,而是直接从内存/硬盘中间读取。

  • 浏览器请求时的强制缓存流程:

a9180333be0072fbf2e84625290f7845.png

  • 强制缓存,响应的Header有两个头部(Expries、Cache-Control):

    • Expries:
      • Expries.png
      • Expires是HTTP1.0的产物,现在已经被 Cache-Control 替代。它的值为服务端返回的到期时间,当下一次请求时,如果 请求时间 < 到期时间,就直接命中缓存。
      • 缺点:到期时间是由服务端生成的,如果客户端时间跟服务器时间不一致,这就会导致缓存命中的误差。
    • Cache-Control:
      • cache-control.png
      • 常见取值:privatepublicno-cachemax-ageno-store,默认为private
    • max-age:设置资源可以被缓存多长时间,单位: s
    • s-maxage:和max-age一样,不过它只针对代理服务器缓存
    • public:指示响应可被任何缓存区缓存
    • private:只针对个人用户,不能被代理服务器缓存
    • no-cache:强制客户端直接向服务器发送请求。 服务器接收到请求,判断资源是否变更,是则返回新内容和200,否则返回304实际上no-cache是会被缓存的,只不过每次在向客户端(浏览器)提供响应数据时,缓存都要向服务器评估缓存响应的有效性。
    • no-store:禁止一切缓存(这个才是响应不被缓存的意思)。
    • 优先级:如果在Cache-Control响应头设置了 max-age 或者 s-maxage 指令,那么 Expires 头会被忽略。

协商缓存

  • 当客户端第二次向服务器请求相同的资源时,先向服务器发送请求”询问”该请求的文件缓存在本地与服务器相比是否更改,如果更改,则更新文件,如果没有就从内存/硬盘中读取。
  • 协商缓存流程:

178676dfcaf4a658559f8a5bafc7d4cb.png

  • 协商缓存,响应的Header有两个字段来表明规则(可以一起使用):
    • Last-Modified / If-Modified-Since
      • 先出现,服务器响应请求时,返回的资源标识: Last-Modified 存储的是资源最后修改的时间,单位是s,之后再次请求时,会带上资源标识:If-Modified-Since,它和最后的修改时间进行对比,如果一致,就会命中缓存返回304,否则返回200和新的资源和资源标识。
    • Etag / If-None-Match(更精确,优先级高)
      • Etag的出现是为了解决Last-modified所存在的一些问题。
      • Etag是资源的唯一标识(生成规则由服务器决定的一串哈希值),再次请求时由If-None-Match返回进行校验。校验对比一致则命中缓存304,否则返回200和新的资源和资源标识。
    • 区别:
      • ETag因为需要进行计算所以服务器的开销更大。
      • 当周期性的更改文件的时间,但是并没有更改文件的内容时,会导致缓存失效。
      • Last-modified只能精确到秒,如果一个文件在1秒内更改了多次,那么无法更新到最新的数据,而Etag的精确度更高。
      • 某些服务器不能精确的得到文件的最后修改时间。

协商缓存和强制缓存优先级

  • 强制缓存 > 协商缓存

  • 流程:先判断强制缓存,如果强制缓存生效,直接使用缓存;如果强制缓存失效,再发请求跟服务器协商,看要不要使用缓存。

9444b4ba6a2a4239310124f68e79d71a.png

总结

  • Http缓存分为强制缓存协商缓存
    • 强制缓存不需要发送请求直接命中。Headers有Expires(基本淘汰)和Cache-Control(一般有六个可选取值)。
      • Expires的值设置一个时间,表示这个时间之前缓存都有效。
      • Cache-Controlmax-age设置一个缓存有效的时间长度,单位s优先级高
    • 协商缓存需要浏览器向服务器协商是否使用缓存。有两对头部:Last-Modified / If-Modified-SinceEtag / If-None-Match,前者在Response Headers中,后者在Request Headers中。
      • Last-Modified是资源最后一次修改的时间,精度s
      • ETag是一串hash值,是资源的唯一标识,每次修改都会改变,精度更高,且优先级高
  • 强制缓存协商缓存都存在的情况下,先判断强制缓存是否生效,如果生效,不用发起请求,直接用缓存。如果强制缓存不生效再发起请求判断协商缓存