03.前端缓存-强缓存协商缓存总结

Posted 宋哈哈

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了03.前端缓存-强缓存协商缓存总结相关的知识,希望对你有一定的参考价值。

缓存的作用

1.减少重复的数据传输,节省流量,节省网费
2.减轻服务器负担,不至于量很大时,服务器吞吐量上限,导致吞吐速度变慢,从而提升性能
3.加快客户端访问速度,无需请求服务器,直接使用客户端缓存,立即呈现

缓存分类

强缓存

强缓存存在客户端缓存数据库中,如果生效,不需要与服务器发生交互

强缓存生效

强制缓存,在缓存数据未失效的情况下,可以直接使用缓存数据

强缓存规则失效

在没有缓存数据的时候,浏览器向服务器请求数据时,服务器会将数据和缓存规则一并返回,缓存规则信息包含在响应header中

对比缓存(协商缓存)

  • 需要进行比较判断是否可以使用缓存。即常见的304 Not Modified 状态码,是客户端与服务器协商的结果,需要与服务器发生交互。
  • 浏览器第一次请求数据时,服务器会将缓存标识与数据一起返回给客户端,客户端将二者备份至缓存数据库中。
  • 再次请求数据时,客户端将备份的缓存标识发送给服务器,服务器根据缓存标识进行判断,判断成功后,返回304状态码,通知客户端比较成功,可以使用缓存数据。

协商缓存生效

协商缓存失效

强缓存与协商缓存优先级

两者可以同时存在,强缓存优先级高于协商缓存,当强缓存生效时,直接使用客户端本地缓存,不再执行协商缓存规则

强缓存

Expires

缓存过期时间(它是http1.0的产物,比Cache-Control http:1.1的产物 的优先级低),用来指定资源到期的时间,是服务器端的具体的时间点,也就是说, Expires=max-age + 请求时间 ,需要和Last-modified结合使用。Expires是Web服务器响应消息头字段,在响应http请求时告诉浏览器在过期时间前浏览器可以直接从浏览器缓存取数据,而无需再次请求。

Cache-Control

优先级比Expires高,有以下取值

  • public 所有内容都将被缓存(客户端和代理服务器都可缓存)
  • private 所有内容只有客户端可以缓存,Cache-Control的默认取值
  • no-cache 客户端缓存内容,但是是否使用缓存则需要经过协商缓存来验证决定
  • no-store 所有内容都不会被缓存,即不使用强制缓存,也不使用协商缓存
  • max-age=xxx (xxx is numeric) 缓存内容将在xxx秒后失效

协商缓存

Last-Modified

  1. Last-Modified:响应时告诉客户端此资源的最后修改时间
  2. If-Modified-Since:当强缓存过期时(使用Cache-Control标识不为no-store),发现资源具有Last-Modified声明,则再次向服务器请求时带上头If-Modified-Since
  3. 服务器收到请求后发现有头If-Modified-Since则与被请求资源的最后修改时间进行比对。若最后修改时间较新,说明资源又被改动过,则响应最新的资源内容并返回200状态码
  4. 若最后修改时间和If-Modified-Since一样,说明资源没有修改,则响应304表示未更新,告知浏览器继续使用所保存的缓存文件

ETag

ETag是实体标签的缩写,根据实体内容生成的一段hash字符串,可以标识资源的状态。当资源发生改变时,ETag也随之发生变化。 ETag是Web服务端产生的,然后发给浏览器客户端

  1. 客户端想判断缓存是否可用可以先获取缓存中文档的ETag,然后通过If-None-Match发送请求给Web服务器询问此缓存是否可用。
  2. 服务器收到请求,将服务器的中此文件的ETag,跟请求头中的If-None-Match相比较,如果值是一样的,说明缓存还是最新的,Web服务器将发送304 Not Modified响应码给客户端表示缓存未修改过,可以使用。
  3. 如果不一样则Web服务器将发送该文档的最新版本给浏览器客户端

为什么需要ETag?

既然有了Last-Modified,为什么需要ETag?

先看一下Last-Modified值的格式 Sat Apr 08 2023 15:17:34 GMT+0800 (GMT+08:00)

  1. 某些服务器不能精确得到文件的最后修改时间, 这样就无法通过最后修改时间来判断文件是否更新了。
  2. 些文件的修改非常频繁,在秒以下的时间内进行修改. Last-Modified只能精确到秒
  3. 一些文件的最后修改时间改变了,但是内容并未改变。 我们不希望客户端认为这个文件修改了。
  4. 如果同样的一个文件位于多个CDN服务器上的时候内容虽然一样,修改时间不一样。

前端 · 面试 HTTP 总结—— HTTP 强缓存

前言

通过上一篇的总结,我们知道 HTTP 缓存分为两种:

  • 强缓存
  • 协商缓存

今天我们就先来了解一下强缓存相关的内容。

强缓存

特点

强缓存中,当请求再次发出时,浏览器会判断目标资源是否“命中”强缓存,如果命中则直接从缓存中获取资源,不会再与服务端发生通信。

在 Chrome 中,命中强缓存的情况下, Network 中显示的 HTTP 状态码是 200 ,比如:

规则

强制缓存的请求结果有两种情况:

  • 命中缓存
  • 未命中缓存

命中缓存

未命中缓存

分类

在 Chrome 中,强缓存又分为:

  • Disk Cache

    缓存资源在硬盘中,浏览器(或页面标签)关闭后硬盘中的缓存不会消失,下次进入页面还能从硬盘中获取。

  • Memory Cache

    缓存资源在内存中,浏览器(或页面标签)关闭后内存中的缓存就会被释放,重新打开页面取不到该缓存。

缓存存放的位置是由浏览器控制的。

属性

是否强缓存由以下 3 个 Header 属性共同来控制:

  • Expires
  • Cache-Control
  • Pragma

Expires

Expires 的值是一个 HTTP 日期,当服务器返回响应时,在 Response Headers 中将过期时间写入 Expires 字段。

在浏览器发起请求时,会根据系统时间和 Expires 的值进行比较,如果系统时间超过了 Expires 的值,缓存失效,会继续从服务器获取资源,比如:

Expires 的值是一个绝对时间,可以看到上图中的时间点:2021 年 8 月 15 日 07:16:53,这代表:这个资源在这个时间点之前都可以直接从缓存中获取。

但是,使用 Expires 会存在一个问题:由于 Expires 的时间戳是服务器定义的,而本地时间的取值来自客户端,因此 Expires 的工作机制对于客户端时间和服务器时间的一致性要求极高,如果两者的时间存在时差,会带来意料之外的结果。

Expires 的优先级在三个 Header 属性中是最低的。

Cache-Control

是 HTTP 1.1 中新增的属性,为了弥补 Expires 缺陷提出的,提供了更精确细致的缓存功能。Cache-Control 在请求头和响应头中都可以使用:

请求头Cache-Control 字段列表:

  • Cache-Control: max-age=<seconds>
  • Cache-Control: max-stale[=<seconds>]
  • Cache-Control: min-fresh=<seconds>
  • Cache-control: no-cache
  • Cache-control: no-store
  • Cache-control: no-transform
  • Cache-control: only-if-cached

响应头Cache-Control 字段列表:

  • Cache-control: must-revalidate
  • Cache-control: no-cache
  • Cache-control: no-store
  • Cache-control: no-transform
  • Cache-control: public
  • Cache-control: private
  • Cache-control: proxy-revalidate
  • Cache-control: max-age=<seconds>
  • Cache-control: s-maxage=<seconds>

Cache-Control 常见字段的含义:

  • public
    表明响应可以被任何对象(包括:发送请求的客户端,CDN 等代理服务器,等等)缓存,即使是通常不可缓存的内容(例如,该响应没有max-age指令或Expires消息头)。

  • private
    表明响应只能被单个用户缓存,不能作为共享缓存(即代理服务器不能缓存它),私有缓存可以缓存响应内容。

  • no-cache
    可以在本地进行缓存,但每次发请求时,都要向服务器进行验证,如果服务器允许,才能使用本地缓存(即:需要协商缓存)。

  • no-store
    禁止缓存客户端请求或服务器响应的内容,每次都须重新请求服务器拿内容。

  • max-age
    设置缓存存储的最大周期,超过这个时间缓存被视为过期 (单位:秒)。

  • must-revalidate

    在缓存过期前可以使用,过期后必须向服务器验证。

图中 Cache-Control 仅指定了 Max-age,所以默认为 private,缓存时间为 31536000 秒(365 天),也就是说,在 365 天内再次请求这条数据,都会直接获取缓存数据库中的数据,直接使用。

Pragma

Pragma 只有一个属性值,就是 no-cache ,效果和 Cache-Control 中的 no-cache 一致,不使用强缓存,需要与服务器验证缓存是否新鲜,在 3 个头部属性中的优先级最高。

总结

  • Expires 和 Pragma 是 HTTP 1.0的产物,Cache-Control是 HTTP 1.1 的产物。
  • 当 Expires 和 Cache-Control 同时存在时,只有 Cache-Control 生效。
  • 在某些不支持 HTTP 1.1 的环境下,Expires 就会发挥用处,现阶段它的存在只是为了兼容性
  • 大文件,优先缓存至 Disk,小文件优先缓存至 Memory
  • 当内存占用率高的情况下,优先缓存至 Disk

~

~本文完,感谢阅读!

~

以上是关于03.前端缓存-强缓存协商缓存总结的主要内容,如果未能解决你的问题,请参考以下文章

前端 · 面试 HTTP 总结—— HTTP 协商缓存

HTTP之强缓存和协商缓存

HTTP进阶,实战剖析强缓存和协商缓存!

前端 · 面试 HTTP 总结—— HTTP 强缓存

前端 · 面试 HTTP 总结—— HTTP 强缓存

不废话,代码实践带你掌握 强缓存协商缓存!