30分钟搞懂 HTTP 缓存14
发表时间:2022-04-08 19:21来源:稀土掘金 无论你是前端,还是后端,日常工作中都免不了遇到和HTTP缓存相关的问题。比如发现本该更新的文件因为缓存而没有更新,通常的做法给请求资源的文件路径加个时间戳,简单粗暴又有效,但作为一个有追求的程序员,我们不应该仅停留在把问题解决了就OK了的层面上,更进一步,思考是否还有更好的解决方案?针对不同的场景、不同类型的资源,有没有更高效的缓存设计方案?希望你读完这篇文章之后,能对HTTP缓存有更深刻全面的理解,掌握它们,对我们解决日常一些复杂问题会有帮助。 一、HTTP 缓存是什么?简单地说,HTTP 缓存是一种保存资源副本并在下次请求时直接使用该副本的技术。也就是说,当 HTTP 缓存发现请求的资源已经被存储,它会拦截请求,返回该资源的副本,而不会去源服务器重新下载。 如果没有缓存会有什么问题?假设没有缓存,试想一下,客户端多次访问一个原始服务器页面时,服务器会多次传输同一份文档,每次传送给一个客户端。一些相同的内容会在网络中一遍遍地传输。这些冗余的数据传输会耗尽昂贵的网络带宽,降低传输速度,加重Web服务器的负载。 有了缓存,就可以保留第一条服务器响应的副本,后继请求就可以由缓存的副本来应对了,这样可以减少那些流入/流出原始服务器的、被浪费掉了的重复流量。通过复用以前获取的资源,可以显著提高网站和应用程序的性能。除此之外,其他连带的好处也显而易见,比如可以减少网络请求时间、降低带宽消耗、提升性能。 什么样的 HTTP 响应会被客户端缓存?那什么样的响应会被缓存呢?
以上是几种比较常见的情况。 二、什么是私有缓存和共享缓存?私有缓存仅供一个客户端使用的缓存,即客户端上的缓存仅供自己使用,通常只存在于如浏览器这样的客户端上。
共享缓存可以供多个客户端使用的缓存,通常依赖于代理服务器。
概念相关的内容讲完,我们开始深入HTTP缓存具体的工作机制。 三、HTTP 缓存的处理流程在正式开始之前,我们通过下面这张图通过宏观视角了解下HTTP 缓存的处理流程(执行顺序)。
请仔细研究这张图,它很重要,下文中的很多内容都是针对图中的某个环节进行扩展讲解。 四、缓存控制策略:Cache-Control对于网站来说,缓存是达到高性能的重要组成部分,缓存需要合理配置,因为并不是所有资源都是永久不变的。Cache-Control 首部可以对缓存进行控制,Cache-Control 能用于 HTTP 请求和响应中,支持多个指令,以逗号分隔:
下面是对三个容易混淆的指令进行对比说明:
五、客户端的缓存策略客户端的缓存策略主要依赖以下几种实现:
实现也比较简单,通常就是在请求头里附加 缓存资源存放在哪里?在浏览器开发者工具的Network的Size栏会出现的三种情况:
客户端查找缓存的顺序:
六、强制再验证:Pragma: no-cache与
七、缓存的新鲜度什么是缓存的新鲜度?生活中,我们可以通过生产日期确定一个食物是否新鲜,通过保质期确定它是否过期。那缓存通过什么方式确定它是否新鲜和是否过期呢? 在缓存文档过期之前,缓存可以以任意频率使用这些副本,而无需与源服务器联系。当然,除非客户端请求中包含有阻止提供已缓存或未验证资源的首部。一旦已缓存文档过期,缓存就必须与服务器进行核对,询问源服务器该文档是否被修改过,如果被修改过,就要获取一份新鲜(带有新的过期日期)的副本。 如何检测缓存是否新鲜?使用期限:Cache-Control: max-age=秒我们可以通过指定一个缓存的最大使用期限,相对于缓存的创建时间,如果超过了最大使用期限,就说明缓存已经不新鲜了。 举个例子:
如图所示,当响应头中Cache-Control的max-age设置为10秒时,意味着从第一次请求开始,该资源的缓存有效期是10秒,10秒内再次请求该资源会从缓存中读取;超过10秒,则客户端向源服务器发起请求,缓存的有效期又重新开始计时。 过期日期:Expires我们还可以通过指定一个绝对的过期日期,如果过期日期已经过了,就说明缓存已经不新鲜了。
八、服务端再验证什么是服务端再验证?仅仅是已缓存文档过期了并不意味着它和源服务器上的文档有实际的区别,这只是意味着要和服务器进行核对了,说明缓存需要询问源服务器文档是否发生了变化,这种情况称为“服务器再验证”。 服务端再验证有两种情况:
如何进行服务端再验证?修改日期再验证:If-Modified-Since最常见的缓存再验证首部是If-Modified-Since。 它的意思是,只有自某个日期之后资源发生了变化的时候,服务器才会执行请求:
实体标签再验证:If-None-Match
有些情况下仅使用最后修改日期进行再验证是不够的,比如:
为了解决这些问题,HTTP允许用户对被称为实体标签(ETag)的“版本标识符”进行比较。 如果缓存中有一个实体标签ETag,它会与源服务器进行再验证,如果服务器上的实体标签仍然与之匹配,会返回一条 304 NotModified 响应。如果服务器上的实体标签已经发生了变化,服务器会在一个 200 OK 响应中返回新的内容以及相应的新 Etag。
什么时候使用修改日期再验证和实体标签再验证?
如果HTTP/1.1缓存或服务器收到的请求既带有 If-Modified-Since,又带有 If-None-Match,那么只有这两个条件都满足时,才能返回304 Not Modified响应。 结尾感谢你耐心的读到这里,HTTP 缓存是不是很简单?学以致用,如果上面的内容你都掌握了,日常工作中遇到和缓存相关的问题,相信你已经可以得心应手。 针对工作中的特殊场景,如何制定高效的缓存设计方案,相信也有了答案。限于篇幅,HTTP 缓存的部分知识并没有讲的面面俱到,你可以在网上找到更详细的参考资料来学习它们——当你需要用到它们的时候。 作者:Kaifang 链接:https://juejin.cn/post/7057085556156547085 来源:稀土掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
文章分类:
学习交流
|