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

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

前言

通过前面的介绍,我们知道 HTTP 缓存分为两种:

  • 强缓存
  • 协商缓存

在上一篇文章中,我们了解了 HTTP 强缓存,今天我们来了解一下协商缓存相关的内容。

协商缓存

特点

协商缓存,也称为对比缓存,从名称可以看出,它没有强制缓存那么霸道,可以有商有量的来确定是否使用缓存资源。

协商缓存机制下,浏览器需要发送缓存标识,去向服务器验证缓存标识是否有效,进而判断是重新发起请求、下载完整的响应,还是从本地获取缓存的资源。

如果服务端提示缓存资源未改动(Not Modified),资源会被重定向到浏览器缓存,这种情况下网络请求对应的状态码是 304,比如:

规则

协商缓存的整体规则如下所示:

从上图可以看出,虽然客户端仍然发起了 HTTP 请求服务器,但是服务器只做了标志对比来确认是否使用缓存,如果确认使用缓存,就不会再返回具体的资源了。这样做虽然没有减少请求数量,但是极大减小了请求负荷,可以明显提升请求速度和减小网络带宽。

上图是缓存标识正常有效的时序图,但其实协商缓存的验证结果也存在两种情况:

  • 标识有效
  • 标识过期

协商缓存需要配合强缓存使用,使用协商缓存需要先设置 Cache-Control:no-cache 或者 pragma:no-cache 来告诉浏览器不走强缓存。

标识过期

属性

对于协商缓存来说,缓存标识的传递是我们着重需要理解的,它在 Response Header 和 Request Header 之间进行传递。

缓存标识可以分为两类:

  • Last-Modified 和 If-Modified-Since
  • Etag 和 If-None-Match

我们一般会说,协商缓存的缓存标识是 Last-Modified(最后修改时间) 和 Etag(标签或名称),因为它们两个都是由服务端确定并返回的。

浏览器携带的是具有判断意味的属性 —— If-Modified-Since(从什么时间以来是否改变) 和 If-None-Match(是否匹配不到)。

缓存标识的携带位置如下图所示:

在具体的网络请求中,缓存标识如下图所示:

Last-Modified 和 If-Modified-Since

Last-Modified 和 If-Modified-Since 是 HTTP 1.0 引入的。

Last-Modified

当浏览器第一次访问一个资源的时候,服务器会在 Response 、Header 中返回一个 Last-Modified,代表这个资源最后的修改时间。

If-Modified-Since

再次请求服务器时,请求头会携带此字段,值为上次请求时服务器返回的 Last-Modified 的值。

服务器收到请求后发现有头 If-Modified-Since 则与被请求资源的最后修改时间进行比对:

  • 若资源的最后修改时间大于 If-Modified-Since,说明资源又被改动过,则响应整片资源内容,返回状态码 200 和最新的资源,响应头中携带最新的缓存标识 Last-Modified。
  • 若资源的最后修改时间小于或等于 If-Modified-Since,说明资源无新修改,则响应 HTTP 304,告知浏览器继续使用所保存的 cache。

缺陷

使用 Last-Modified 是有一定缺陷的:

  • 如果资源更新的速度是秒以下单位,那么该缓存是不能被使用的,因为 If-Modified-Since 只能检查到以秒为最小计量单位的时间差。
  • 如果文件是通过服务器动态生成的,那么该方法的更新时间永远是生成的时间,尽管文件可能没有变化,所以起不到缓存的作用。
  • 我们编辑了文件,但文件的内容没有改变。服务端并不清楚我们是否真正改变了文件,它仍然通过最后编辑时间进行判断。因此这个资源在再次被请求时,会被当做新资源,进而引发一次完整的响应——不该重新请求的时候,也会重新请求。

为了解决上面服务器没有正确感知文件变化的问题,Etag 作为 Last-Modified 的补充出现了。

Etag 和 If-None-Match

Etag 和 If-None-Match 是一对报文头,属于HTTP 1.1。

ETag 和 If-None-Match 的值是一串 hash 码,代表的是一个资源的标识符,当服务端的文件变化的时候,它的 hash 码会随之改变。

Etag

服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器决定)。

ETag 又有强弱校验之分,如果 hash 码是以 “W/” 开头的一串字符串,说明此时协商缓存的校验是弱校验的,只有服务器上的文件差异(根据 ETag 计算方式来决定)达到能够触发 hash 值后缀变化的时候,才会真正地请求资源,否则返回 304 并加载浏览器缓存。

If-None-Match

再次请求服务器时,通过此字段通知服务器客户段缓存数据的唯一标识。

服务器收到请求后发现有头 If-None-Match 则与被请求资源的唯一标识进行比对:

  • 不同,说明资源又被改动过,则响应整片资源内容,返回状态码 200。
  • 相同,说明资源无新修改,则响应 HTTP 304,告知浏览器继续使用所保存的 cache。

缺陷

Etag 的生成过程需要服务器额外付出开销,会影响服务端的性能,这是它的弊端。

因此启用 Etag 需要我们审时度势:

  • Etag 并不能替代 Last-Modified,它只能作为 Last-Modified 的补充和强化存在。
  • Etag 在感知文件变化上比 Last-Modified 更加准确,优先级也更高。
  • 当 Etag 和 Last-Modified 同时存在时,以 Etag 为准。

两种属性比较

  • 在精确度上,Etag 要优于 Last-Modified,Last-Modified 的时间单位是秒,如果某个文件在 1 秒内改变了多次,那么他们的 Last-Modified 其实并没有体现出来修改,但是 Etag 每次都会改变确保了精度。
  • 在性能上,Etag 要逊于 Last-Modified,毕竟 Last-Modified 只需要记录时间,而 Etag 需要服务器通过算法来计算出一个 hash 值。
    在优先级上,服务器校验优先考虑 Etag。

总结

总结一下上面的内容:

  • 协商缓存是依靠缓存标识来判断资源是否有效。
  • 缓存标识包括 Last-Modified(If-Modified-Since)和 Etag(If-None-Match)。
  • 响应头携带的是 Last-Modified 和 Etag。
  • 请求头携带的是 If-Modified-Since 和 If-None-Match。
  • Etag 是 Last-Modified 的补充和完善,并不能完全替代 Last-Modified。
  • Etag 的优先级高于 Last-Modified。
  • Last-Modified 的性能要高于 Etag,但是精确性却逊色于 Etag。

以上就是 HTTP 协商缓存的相关内容。

~

~本文完,感谢阅读!

~

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

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

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

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

【前端 · 面试 】HTTP 总结(九)—— HTTP 协商缓存相关推荐

  1. 前端面试技巧和注意事项_前端面试百分之九十九过的技巧

    2020最全的前端面试指南,一个多月 1.8w 字的面试经验积累,凭借它最终成功入职大厂-- 今年的金三银四刚好赶上疫情,很多大公司都停止招聘甚至裁员,想跳槽的小伙伴被打的措手不及. 需求减少要求肯定 ...

  2. 前端面试十有九问之原型链

    1.原型链是什么? 原型指的是原型属性,原型也是一个对象. 当访问一个对象的属性时,如果这个对象内部不存在这个属性,那么它就会去它的原型对象里找这个属性,这个原型对象又会有自己的原型,于是就这样一直找 ...

  3. 前端面试查漏补缺--(一) 防抖和节流

    前言 本系列最开始是为了自己面试准备的.后来发现整理越来越多,差不多有十二万字符,最后决定还是分享出来给大家. 为了分享整理出来,花费了自己大量的时间,起码是只自己用的三倍时间.如果喜欢的话,欢迎收藏 ...

  4. 今日头条前端面试总结

    今天早晨刚刚结束了今日头条的前段实习生面试.总的下来感觉自己答的一般,感觉以前看东西太浅尝辄止了,导致了今天的面试有很多细节答不上来.现凭着记忆记录一下碰到的题目. 上来首先是自我介绍,然后问为什么选 ...

  5. 前端面试查漏补缺--(二) 垃圾回收机制

    前言 本系列最开始是为了自己面试准备的.后来发现整理越来越多,差不多有十二万字符,最后决定还是分享出来给大家. 为了分享整理出来,花费了自己大量的时间,起码是只自己用的三倍时间.如果喜欢的话,欢迎收藏 ...

  6. 前端面试查漏补缺--(三) 跨域及常见解决办法

    前言 本系列最开始是为了自己面试准备的.后来发现整理越来越多,差不多有十二万字符,最后决定还是分享出来给大家. 为了分享整理出来,花费了自己大量的时间,起码是只自己用的三倍时间.如果喜欢的话,欢迎收藏 ...

  7. 前端面试查漏补缺--(十) 前端鉴权

    前言 本系列最开始是为了自己面试准备的.后来发现整理越来越多,差不多有十二万字符,最后决定还是分享出来给大家. 为了分享整理出来,花费了自己大量的时间,起码是只自己用的三倍时间.如果喜欢的话,欢迎收藏 ...

  8. 前端协商缓存强缓存如何使用_前端强缓存和协商缓存

    缓存是前端面试的一个常见知识点,下面对于实际项目中如何进行缓存的设置给出方案. 强缓存和协商缓存 浏览器缓存是浏览器将用户请求过的静态资源存储到电脑本地磁盘中,当再次访问时,就可以直接从本地缓存中加载 ...

  9. 前端对所有文件请求添加header_【前端面试必问】浏览器缓存原理?送你满分答案...

    (本文适合所1-3年的前端阅读) 原文链接: http://blog.poetries.top/2019/01/02/browser-cache/ 一.浏览器缓存基本认识 分为强缓存和协商缓存 浏览器 ...

最新文章

  1. 视频驱动V4L2子系统驱动架构 - ioctl
  2. frp 0.11.0 发布新版,支持很多新功能
  3. 【CyberSecurityLearning 附】python3-requests模块
  4. AndroidStudio_开发工具的设置_界面设置_字体设置_使用习惯设置_按钮设置等一些设置的介绍---Android原生开发工作笔记71
  5. Varnish——CDN加速的实现(多个后端服务器实现负载均衡、虚拟主机)
  6. IOS开发之多线程 -- GCD的方方面面
  7. 收获,不止oracle
  8. eclipse3.7.2+KEmulator搭建J2ME开发环境
  9. TCP和Udp的区别是什么?
  10. html空格折叠原因,html – 使用Bootstrap列折叠空白
  11. REST,以及RESTful的讲解
  12. VB6 自定义 Msgbox 和 InputBox 消息框
  13. paddlepaddle 9 MC Dropout的使用
  14. 短信API整合在spring里面(3)
  15. 认识中药(3)--桔(jie)梗
  16. RTP:一种实时应用的传输协议 (RFC-3550)
  17. Inverse Fourier transform
  18. 笔记本更换网络连接,MAC地址改变!
  19. 22吉大计算机学硕考研389分经验分享
  20. 开发板的基础知识与分类

热门文章

  1. 解决windows系统无法对docker容器进行端口映射的问题
  2. Java:Linux上java -jar xxx.jar命令执行jar包时出现Error: Invalid or corrupt jarfile xxx.jar解决方案
  3. Google 已将“xxxx”标记为恶意扩展程序并阻止安装,解决方案
  4. 终极解决VS2015 安装失败问题,如 安装包损坏或丢失
  5. 解决sublime text 3使用Install Package时出现There are no packages available for installation问题
  6. stm32h7内存分配_stm32h7“分散加载方式管理多块内存”
  7. python有关迭代器和生成器的面试题_python面试题之生成器迭代器
  8. 苹果id可以同时用两个手机吗_科技V报余承东:鸿蒙OS随时可用于手机;疑似魅族16s Pro通过3C认证20190809...
  9. JDBC中给Mysql加时区问题!
  10. 数据结构与与算法之希尔排序