最近我在做前端面试题总结系列,感兴趣的朋友可以添加关注,欢迎指正、交流。

争取每个知识点能够多总结一些,至少要做到在面试时,针对每个知识点都可以侃起来,不至于哑火。

HTTP 强缓存和协商缓存

前言

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

  • 强缓存
  • 协商缓存

HTTP 缓存分类

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

强缓存

特点

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

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

image-20210808211159084

规则

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

  • 命中缓存
  • 未命中缓存

命中缓存

image-20210808212126564

未命中缓存

image-20210808212546662

分类

在 Chrome 中,强缓存又分为:

  • Disk Cache

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

  • Memory Cache

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

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

image-20210808210306482

如果不想从强缓存中获取资源,Windows 电脑可以通过 Ctrl + F5 刷新页面,Mac OS 可以通过 Shift + Command + R 刷新页面,刷新后你可以看到资源不会出现 from disk(or memory) cache 了。

属性

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

  • Expires
  • Cache-Control
  • Pragma

Expires

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

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

image-20210808211410000

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

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

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

Expires 字段是 HTTP 1.0 时代的产物,现在的浏览器用的全都是 HTTP 1.1 了,所以这个字段的作用基本可以忽略 。

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

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

image-20210808214220870

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

在 HTTP 1.1 标准试图将缓存相关配置收敛进 Cache-Control 这样的大背景下, Max-age 可以视作是对 Expires 能力的补位/替换。在当下的前端实践里,我们普遍会倾向于使用 Max-age。但如果你的应用对向下兼容有强诉求,那么 Expires 仍然是不可缺少的。

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

~

~本文完,感谢阅读!

~

学习有趣的知识,结识有趣的朋友,塑造有趣的灵魂!

大家好,我是〖编程三昧〗的作者 隐逸王,我的公众号是『编程三昧』,欢迎关注,希望大家多多指教!

你来,怀揣期望,我有墨香相迎! 你归,无论得失,唯以余韵相赠!

知识与技能并重,内力和外功兼修,理论和实践两手都要抓、两手都要硬!

更多相关文章

  1. 【前端 · 面试 】HTTP 总结(七)—— HTTP 缓存概述
  2. 通过canvas作图片缓存
  3. 我们常说的算法时间复杂度和空间复杂度到底是什么?
  4. 21.)PHPWeb开发框架~laravel中缓存系统Cache的使用及配置操作
  5. ThinkPHP 时间戳,写错了,好尴尬
  6. 19.【TP6学习笔记】Cache缓存的设置和清除等使用操作
  7. 又说骚话,Linus再次拒绝Intel CPU漏洞补丁
  8. promise间隔时间添加dom
  9. 时间序列建模三部曲

随机推荐

  1. android发送restful风格的http请求
  2. Android应用程序键盘(Keyboard)消息处理机
  3. 阅读《Android 从入门到精通》(31)——Inte
  4. FregServer进程,获取ServiceManager代理对
  5. Android Studio查看错误信息
  6. 百度地图android开发资料
  7. Android 通过按键旋转屏幕
  8. 2011.07.19——— android intent 传递li
  9. 高德地图自定义点聚合样式Android
  10. android 实现模拟按键