[HTTP]究极详细HTTP缓存流程

947 阅读4分钟

一、什么是HTTP缓存

HTTP缓存属于私有缓存,只能用于单独用户。你可能已经见过浏览器设置中的“缓存”选项。浏览器缓存拥有用户通过 HTTP 下载的所有文档。这些缓存为浏览过的文档提供向后/向前导航,保存网页,查看源码等功能,可以避免再次向服务器发起多余的请求。它同样可以提供缓存内容的离线浏览。

缓存机制的类型是由服务端告知浏览器的,第一次数据请求浏览器在缓存库里没找到缓存数据就直接请求服务器,服务器会带上响应数据和缓存规则一起返回给浏览器,浏览器将其存储就完成里第一次缓存。

二、缓存流程

2.1 第一次请求

没有缓存,未知缓存情况,先以Cache-Control: no-cache请求数据,服务端返回请求的资源数据和该数据的缓存规则。

2.1 强缓存

【强缓存命中】 缓存中有数据且未过期,直接返回

【强缓存未命中】 缓存有数据但已失效,再判断协商缓存

2.2 协商缓存

【协商缓存命中】

【协商缓存未命中】

2.3 整体流程

Untitled 5.png

三、强缓存和协商缓存的区别

  • 两种缓存规则是可以同时存在的,只不过强缓存权重比协商缓存高,如果强缓存命中就不再看协商缓存了。

  • 服务器更新了资源后,如果是强缓存且没过期,浏览器是不知道资源更新了

  • 强缓存缓存过期了之后即使资源没有变化也是重新去服务器请求存一遍,不会用已有的缓存

  • 协商缓存每次的都会去和服务器验证是否最新,如果没变化就会用已有的缓存。

  • 缓存常见应用:

    1. 协商缓存常用于时常变更的资源,如HTML
    2. 强缓存一般存储较为固定的资源,如 js、image、css,文件名带hash值否则会遇到浏览器资源不更新的问题。

四、缓存常用字段

4.1 HTTP 1.0 缓存方案

  • Pragma

    • ⬅️ ➡️ 请求/响应头,缓存控制字段,与http1.1的 Cache-Control 基本相同

    • 权重更高,当该字段值为no-cache的时候,会告诉浏览器不要对该资源缓存,Expires、Cache-Control配置都将失效

  • Expires

    • ⬅️ 响应头,代表该资源的过期时间。
    • 配置如,Expires: Thu, 19 Aug 2021 16:00:00 GMT,是一个绝对时间。
    • 客户端在需要请求数据的时候,首先会对比当前系统时间和这个Expires时间,如果没有超过Expires时间,则直接读取本地磁盘中的缓存数据,不发送请求。

4.2 HTTP 1.1 缓存方案

  • Cache-Control

    • ⬅️ ➡️ 请求/响应头,缓存控制字段,精确控制缓存策略。
    • 请求头字段
      • max-age= 缓存保存多长时间
      • max-stale[=] 缓存过期多久之内还能接受
      • min-fresh= 希望获取一个多久时间内还能保持最新的数据
      • no-cache 强制请求服务器验证[协商缓存验证]
      • no-store 不使用任何缓存
      • no-transform 不允许代理修改请求头(没啥用
      • only-if-cached 只从缓存中取资源,不请求服务端,若请求无缓存返回504
    • 响应头字段
      • must-revalidate 过期后,在成功向服务器验证之前,缓存不能用该资源响应后续请求。
      • no-cache 同上
      • no-store 同上
      • no-transform 同上
      • public 表明响应可以被任何对象缓存(包括:发送请求的客户端,代理服务器,等等)
      • private 表明响应只能被单个用户缓存,不能作为共享缓存(即代理服务器不能缓存它)
      • proxy-revalidate 与must-revalidate相同,但仅适用于共享缓存,并被私有缓存忽略
      • max-age= 同上
      • s-maxage= 同上
  • If-Modified-Since

    • ➡️ 请求头,缓存中保存的资源最近修改时间,由浏览器告诉服务器。
    • 配置如,If-Modified-Since: Thu, 19 Aug 2021 06:32:35 GMT
  • Last-Modified

    • ⬅️ 响应头,服务端真实的资源最近修改时间,由服务器告诉浏览器。
    • 配置如,Last-Modified: Thu, 19 Aug 2021 06:32:35 GMT
  • If-None-Match

    • ➡️ 请求头,缓存中保存的缓存资源标识,由浏览器告诉服务器。
    • 配置如,If-None-Match: "611dfb03-6e28"
  • Etag

    • ⬅️ 响应头,服务端真实的资源标识,由服务器告诉浏览器。
    • 配置如,ETag: "611dfb03-6e28"