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

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

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


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


14.png


前言


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


  • 强缓存
  • 协商缓存


13.png


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


协商缓存


特点


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


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


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


00.png


规则


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


11.png


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


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


  • 标识有效
  • 标识过期


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


标识过期


10.png


属性


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


缓存标识可以分为两类:


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


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


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


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


9.png


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


8.png


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 协商缓存的相关内容。


~本文完,感谢阅读!


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


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


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


相关文章
|
2月前
|
前端开发 JavaScript 安全
前端性能调优:HTTP/2与HTTPS在Web加速中的应用
【10月更文挑战第27天】本文介绍了HTTP/2和HTTPS在前端性能调优中的应用。通过多路复用、服务器推送和头部压缩等特性,HTTP/2显著提升了Web性能。同时,HTTPS确保了数据传输的安全性。文章提供了示例代码,展示了如何使用Node.js创建一个HTTP/2服务器。
69 3
|
2月前
|
缓存 NoSQL 关系型数据库
大厂面试高频:如何解决Redis缓存雪崩、缓存穿透、缓存并发等5大难题
本文详解缓存雪崩、缓存穿透、缓存并发及缓存预热等问题,提供高可用解决方案,帮助你在大厂面试和实际工作中应对这些常见并发场景。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:如何解决Redis缓存雪崩、缓存穿透、缓存并发等5大难题
|
2月前
|
SQL 缓存 关系型数据库
美团面试:Mysql 有几级缓存? 每一级缓存,具体是什么?
在40岁老架构师尼恩的读者交流群中,近期有小伙伴因未能系统梳理MySQL缓存机制而在美团面试中失利。为此,尼恩对MySQL的缓存机制进行了系统化梳理,包括一级缓存(InnoDB缓存)和二级缓存(查询缓存)。同时,他还将这些知识点整理进《尼恩Java面试宝典PDF》V175版本,帮助大家提升技术水平,顺利通过面试。更多技术资料请关注公号【技术自由圈】。
美团面试:Mysql 有几级缓存? 每一级缓存,具体是什么?
|
2月前
|
存储 缓存 网络协议
计算机网络常见面试题(二):浏览器中输入URL返回页面过程、HTTP协议特点,GET、POST的区别,Cookie与Session
计算机网络常见面试题(二):浏览器中输入URL返回页面过程、HTTP协议特点、状态码、报文格式,GET、POST的区别,DNS的解析过程、数字证书、Cookie与Session,对称加密和非对称加密
|
2月前
|
前端开发 安全 应用服务中间件
前端性能调优:HTTP/2与HTTPS在Web加速中的应用
【10月更文挑战第26天】随着互联网的快速发展,前端性能调优成为开发者的重要任务。本文探讨了HTTP/2与HTTPS在前端性能优化中的应用,介绍了二进制分帧、多路复用和服务器推送等特性,并通过Nginx配置示例展示了如何启用HTTP/2和HTTPS,以提升Web应用的性能和安全性。
42 3
|
2月前
|
缓存 前端开发 JavaScript
"面试通关秘籍:深度解析浏览器面试必考问题,从重绘回流到事件委托,让你一举拿下前端 Offer!"
【10月更文挑战第23天】在前端开发面试中,浏览器相关知识是必考内容。本文总结了四个常见问题:浏览器渲染机制、重绘与回流、性能优化及事件委托。通过具体示例和对比分析,帮助求职者更好地理解和准备面试。掌握这些知识点,有助于提升面试表现和实际工作能力。
69 1
|
3月前
|
前端开发 JavaScript 中间件
前端全栈之路Deno篇(四):Deno2.0如何快速创建http一个 restfulapi/静态文件托管应用及oak框架介绍
Deno 是由 Node.js 创始人 Ryan Dahl 开发的新一代 JavaScript 和 TypeScript 运行时,旨在解决 Node.js 的设计缺陷,具备更强的安全性和内置的 TypeScript 支持。本文介绍了如何使用 Deno 内置的 `Deno.serve` 快速创建 HTTP 服务,并详细讲解了 Oak 框架的安装和使用方法,包括中间件、路由和静态文件服务等功能。Deno 和 Oak 的结合使得创建 RESTful API 变得高效且简便,非常适合快速开发和部署现代 Web 应用程序。
133 2
|
3月前
|
缓存 监控 算法
小米面试题:多级缓存一致性问题怎么解决
【10月更文挑战第23天】在现代分布式系统中,多级缓存架构因其能够显著提高系统性能和响应速度而被广泛应用。
93 3
|
4月前
|
Web App开发 前端开发 Linux
「offer来了」浅谈前端面试中开发环境常考知识点
该文章归纳了前端开发环境中常见的面试知识点,特别是围绕Git的使用进行了详细介绍,包括Git的基本概念、常用命令以及在团队协作中的最佳实践,同时还涉及了Chrome调试工具和Linux命令行的基础操作。
「offer来了」浅谈前端面试中开发环境常考知识点
|
3月前
|
存储 缓存 NoSQL
阿里面试题:缓存的一些常见的坑,你遇到过哪些,怎么解决的?
阿里面试题:缓存的一些常见的坑,你遇到过哪些,怎么解决的?