透视 HTTP 协议
罗剑锋(Chrono)
前奇虎 360 技术专家,Nginx/OpenResty 开源项目贡献者
63943 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 48 讲
开篇词 (1讲)
透视 HTTP 协议
15
15
1.0x
00:00/00:00
登录|注册

20 | 生鲜速递:HTTP的缓存控制

HTTP缓存看上去很复杂,但基本原理说白了就是一句话:“没有消息就是好消息”,“没有请求的请求,才是最快的请求”
ETag是“实体标签”(Entity Tag)的缩写,是资源的一个唯一标识,主要是用来解决修改时间无法准确区分文件变化的问题
条件请求一共有5个头字段,最常用的是“If-Modified-Since”和“If-None-Match”
浏览器可以用两个连续的请求组成“验证动作”:先是一个HEAD,获取资源的修改时间等元信息,然后与缓存数据比较
浏览器用“Cache-Control”做缓存控制只能是刷新数据,不能很好地利用缓存数据
条件请求一共有5个头字段,最常用的是“If-Modified-Since”和“If-None-Match”
浏览器的缓存究竟什么时候才能生效
浏览器也可以发送“Cache-Control”字段,使用“max-age=0”或“no_cache”刷新数据
其他缓存控制属性:no-store, no-cache, must-revalidate
服务器标记资源有效期使用的头字段是“Cache-Control”,里面的值“max-age=30”就是资源的有效时间
浏览器收到数据就会存入缓存,如果没过期就可以直接使用,过期就要去服务器验证是否仍然可用
服务器使用“Cache-Control”设置缓存策略,常用的是“max-age”,表示资源的有效期
HTTP传输的每一个环节中都可以有缓存
缓存是优化系统性能的重要手段
小结
条件请求
客户端的缓存控制
服务器的缓存控制
缓存控制
HTTP缓存控制和条件请求

该思维导图由 AI 生成,仅供参考

缓存(Cache)是计算机领域里的一个重要概念,是优化系统性能的利器。
由于链路漫长,网络时延不可控,浏览器使用 HTTP 获取资源的成本较高。所以,非常有必要把“来之不易”的数据缓存起来,下次再请求的时候尽可能地复用。这样,就可以避免多次请求 - 应答的通信成本,节约网络带宽,也可以加快响应速度。
试想一下,如果有几十 K 甚至几十 M 的数据,不是从网络而是从本地磁盘获取,那将是多么大的一笔节省,免去多少等待的时间。
实际上,HTTP 传输的每一个环节基本上都会有缓存,非常复杂。
基于“请求 - 应答”模式的特点,可以大致分为客户端缓存和服务器端缓存,因为服务器端缓存经常与代理服务“混搭”在一起,所以今天我先讲客户端——也就是浏览器的缓存。

服务器的缓存控制

为了更好地说明缓存的运行机制,下面我用“生鲜速递”作为比喻,看看缓存是如何工作的。
夏天到了,天气很热。你想吃西瓜消暑,于是打开冰箱,但很不巧,冰箱是空的。不过没事,现在物流很发达,给生鲜超市打个电话,不一会儿,就给你送来一个 8 斤的沙瓤大西瓜,上面还贴着标签:“保鲜期 5 天”。好了,你把它放进冰箱,想吃的时候随时拿出来。
在这个场景里,“生鲜超市”就是 Web 服务器,“你”就是浏览器,“冰箱”就是浏览器内部的缓存。整个流程翻译成 HTTP 就是:
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

HTTP缓存控制和条件请求是优化系统性能的重要手段。通过“Cache-Control”头字段和条件请求头字段,服务器和浏览器可以灵活控制缓存策略,有效减少网络开销,加快响应速度。常用的缓存控制策略包括“max-age”、“no-store”、“no-cache”和“must-revalidate”,而条件请求头字段包括“if-Modified-Since”和“If-None-Match”,通过与服务器验证资源是否过期,实现缓存的有效复用。此外,文章还介绍了ETag的作用,以及强ETag和弱ETag的区别。总的来说,HTTP缓存控制的基本原理就是“没有消息就是好消息”,有效利用缓存可以减少响应时间、节约网络流量。文章还提出了两个课下作业,分别是比较Cache和Cookie的异同,以及解释强制刷新能够获取最新数据的原因。通过本文的总结,读者可以快速了解HTTP缓存控制和条件请求的重要性,以及如何灵活运用这些策略来优化系统性能。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《透视 HTTP 协议》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(81)

  • 最新
  • 精选
  • 前端西瓜哥
    Cache 和 Cookie 的相同点是:都会保存到浏览器中,并可以设置过期时间。 不同点: 1. Cookie 会随请求报文发送到服务器,而 Cache 不会,但可能会携带 if-Modified-Since(保存资源的最后修改时间)和 If-None-Match(保存资源唯一标识) 字段来验证资源是否过期。 2. Cookie 在浏览器可以通过脚本获取(如果 cookie 没有设置 HttpOnly),Cache 则无法在浏览器中获取(出于安全原因)。 3. Cookie 通过响应报文的 Set-Cookie 字段获得,Cache 则是位于 body 中。 4. 用途不同。Cookie 常用于身份识别,Cache 则是由浏览器管理,用于节省带宽和加快响应速度。 5. Cookie 的 max-age 是从浏览器拿到响应报文时开始计算的,而 Cache 的 max-age 是从响应报文的生成时间(Date 头字段)开始计算。

    作者回复: 总结的非常好。 第三点感觉有点问题,cache缓存的是完整的报文,不单单是body。

    2019-07-13
    4
    87
  • 小鸟淫太
    1. cookie是方便进行身份识,cache是为了减少网络请求。 2. 强制刷新是因为请求头里的 If-Modified-Since 和 If-None-Match 会被清空所以会返回最新数据

    作者回复: 回答正确,之前是我弄错了。

    2019-07-12
    3
    34
  • 对于第二个问题:发现强制刷新后请求头中 没有了 If-None-Match ,而且 Cache-Control: no-cache 是这个原因吗?

    作者回复: 对,没有条件请求头,那么服务器就无法处理缓存,就只能返回最新的数据。

    2019-07-13
    3
    24
  • DENG永青
    Etag的工作原理 Etag在服务器上生成后,客户端通过If-Match或者说If-None-Match这个条件判断请求来验证资源是否修改.我们常见的是使用If-None-Match.请求一个文件的流程可能如下: 新的请求 客户端发起HTTP GET请求一个文件(css ,image,js);服务器处理请求,返回文件内容和一堆Header(包括Etag,例如"2e681a-6-5d044840"),http头状态码为为200. 同一个用户第二次这个文件的请求 客户端在一次发起HTTP GET请求一个文件,注意这个时候客户端同时发送一个If-None-Match头,这个头中会包括上次这个文件的Etag(例如"2e681a- 6-5d044840"),这时服务器判断发送过来的Etag和自己计算出来的Etag,因此If-None-Match为False,不返回200,返 回304,客户端继续使用本地缓存; 注意.服务器又设置了Cache-Control:max-age和Expires时,会同时使用,也就是说在完全匹配If-Modified-Since和If-None-Match即检查完修改时间和Etag之后,服务器才能返回304.

    作者回复: 写的非常详细,点赞。

    2019-08-07
    2
    23
  • 院长。
    老师我有几个问题想问一下: 1. F5刷新的时候,请求头加上"Cache-Control: max-age=0",您文章里说,服务器用一个最新生成的报文回应浏览器,那这时候响应返回的应该是"200 OK"吗?为什么我在极客网页版的这个页面刷新后,有个叫"106804"的资源返回的是"304",但是强制刷新是"200 ok",产生的效果好像不同呀。这里是不是应该换一种方式说?感觉强制刷新说的有些简单了。 2. F5刷新发送的请求头是固定的吗?还是会根据浏览器不同而产生变化? 3. 200(from memory cache)和200(from disk cache)是针对内存和硬盘的,他们出现的场景分别是什么呢? 4. HTTP缓存有标准性的流程吗?比如说从我输入URL开始,到后续刷新或者强制刷新等? 5.对于"must-revalidate"我有疑问,本身存储机制不就是如果不过期的话可以继续使用,过期的话去请求服务器吗?那这个属性还有什么意义呢? 6. no-cache,no-store,max-age等属性可以共存吗? 问题有点多,因为网上资料质量参差不齐,解释有些也不全相同,所以在这里咨询下老师,希望老师可以解答一下,或者有推荐的讲述HTTP缓存的文章也可以,谢谢老师

    作者回复: 1.强制刷新请求最新的资源,没有条件请求,所以不会有304,都是200。 2.每个浏览器可能会有不同,但基本的字段是一样的。 3.缓存的位置不一样,浏览器会分别存放到内存或者硬盘上,所以会显示来源不同。 4.http只规定了缓存的用法,具体如何存放如何使用就是客户端自己灵活实现了,怎么方便怎么来。 5.过期后去验证,如果服务器返回304,那么就可以继续重用缓存,而不用下载整个资源。 6.可以看一下流程图,不是所以的属性都能共存的。当然如果你要是都写上也不是不可以,那浏览器就会“精神错乱”了。

    2019-07-15
    3
    18
  • 啦啦啦
    老师,nocache,每次使用前都需要去浏览器问一下有没有过期,这不也是一次请求吗?那不和没有缓存一个意思吗

    作者回复: 不一样,如果服务器返回304,是一个很小的报文,这样浏览器就可以直接重用缓存里的数据,可以节约传输带宽。 nostore每次都会传输完整的报文,成本高。

    2019-07-12
    14
  • Marvin
    我有一个问题,就拿咱们极客时间的网页来说,会请求一个Id-00001.ts的文件,响应头中指示了cache-control: max-age= 7200, 要一个小时才过期,那么为什么每次刷新都是304, 像这种情况不应该直接200 cacahe from disk才对么?为什么明明没有过期还要去服务器协商呢?

    作者回复: 刷新时发的是条件请求,不是普通的请求,所以就必须返回304,告诉浏览器内容没有过期,可以继续用缓存。 普通请求才会直接检查缓存,然后是200 cacahe from disk。

    2019-08-04
    2
    12
  • 风宇殇
    这篇文章将缓存讲的比较容易理解。https://mp.weixin.qq.com/s/cUqkG3NETmJbglDXfSf0tg

    作者回复: 挺好的文章,欢迎多来这样的分享。

    2021-03-10
    2
    6
  • Khirye
    Hi, 我对缓存控制策略这张流程图有一些疑惑,must-revalidate是指缓存过期之后,必须要向服务器验证缓存,这一步应该是在图中”缓存最多x秒“这个判断之前的吧? 因为只有缓存超过了max-age的期限,才会进入”must-revalidate的判断“这一步吧? 烦请解惑,谢谢!

    作者回复: 这张图是“服务器”的缓存策略,也就是说服务器应该如何设置资源的缓存参数,并不是客户端判断缓存的流程。 只要不是no-store就必然会设置max-age,所以must-revalidate是max-age的一个附加条件。

    2019-11-25
    6
  • geraltlaush
    小贴士的nginx计算etag我贴下测试logngx_sprintf(etag->value.data, ""%xT-%xO"", r->headers_out.last_modified_time, r->headers_out.content_length_n)相信大家看到这里更清晰明了

    作者回复: great。

    2019-07-21
    6
收起评论
显示
设置
留言
81
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部