http学习 http的缓存控制
一、前言
由于请求-应答模式的通信成本比较高,所以有必要将某些数据进行缓存,从而节省带宽。
缓存是优化系统性能的重要手段,HTTP 传输的每一个环节中都可以有缓存;
二、服务器的缓存控制
2.1 缓存控制的流程
- 浏览器发现缓存无数据,于是发送请求,向服务器获取资源;
- 服务器响应请求,返回资源,同时标记资源的有效期;
- 浏览器缓存资源,等待下次重用。
举个例子:
夏天到了,天气很热。你想吃西瓜消暑,于是打开冰箱,但很不巧,冰箱是空的。不过没事,现在物流很发达,给生鲜超市打个电话,不一会儿,就给你送来一个 8 斤的沙瓤大西瓜,上面还贴着标签:“保鲜期 5 天”。好了,你把它放进冰箱,想吃的时候随时拿出来。
2.2 服务器使用“Cache-Control”设置缓存策略
- max-age
服务器使用“Cache-Control”设置缓存策略,常用的是“max-age”,表示资源的有效期;
浏览器收到数据就会存入缓存,如果没过期就可以直接使用,过期就要去服务器验证是否仍然可用;
- no-store
不允许缓存,用于某些变化非常频繁的数据,例如秒杀页面;
- no-cache
它的字面含义容易与 no-store 搞混,实际的意思并不是不允许缓存,而是可以缓存,但在使用之前必须要去服务器验证是否过期,是否有最新的版本;
- must-revalidate
又是一个和 no-cache 相似的词,它的意思是如果缓存不过期就可以继续使用,但过期了如果还想用就必须去服务器验证。
举例说明一下:
no-store:买来的西瓜不允许放进冰箱,要么立刻吃,要么立刻扔掉;
no-cache:可以放进冰箱,但吃之前必须问超市有没有更新鲜的,有就吃超市里的;
must-revalidate:可以放进冰箱,保鲜期内可以吃,过期了就要问超市让不让吃。
如图:
三、客户端的缓存控制
其实不止服务器可以发“Cache-Control”头,浏览器也可以发“Cache-Control”,也就是说请求 - 应答的双方都可以用这个字段进行缓存控制,互相协商缓存的使用策略。
刷新
当你点“刷新”按钮的时候,浏览器会在请求头里加一个“Cache-Control: max-age=0”。因为 max-age 是“生存时间”,max-age=0 的意思就是“我要一个最最新鲜的西瓜”,而本地缓存里的数据至少保存了几秒钟,所以浏览器就不会使用缓存,而是向服务器发请求。服务器看到 max-age=0,也就会用一个最新生成的报文回应浏览器。
Ctrl+F5 的“强制刷新”
强制刷新是因为请求头里的 If-Modified-Since 和 If-None-Match 会被清空所以会返回最新数据
“前进”“后退”
这些重定向动作中浏览器不会“夹带私货”,只用最基本的请求头,没有“Cache-Control”,所以就会检查缓存,直接利用之前的资源,不再进行网络通信。
四、条件请求
4.1 条件请求
HTTP 协议就定义了一系列“If”开头的“条件请求”字段,专门用来检查验证资源是否过期。
验证资源是否失效需要使用“条件请求”,常用的是“if-Modified-Since”和“If-None-Match”,收到 304 就可以复用缓存里的资源;
验证资源是否被修改的条件有两个:“Last-modified”和“ETag”,需要服务器预先在响应报文里设置,搭配条件请求使用;
4.2 ETag
ETag 是“实体标签”(Entity Tag)的缩写,是资源的一个唯一标识,主要是用来解决修改时间无法准确区分文件变化的问题。
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为Fals,不返回200,返回304,客户端继续使用本地缓存;
注意,服务器又设置了Cache-Control:max-age和Expires时,会同时使用,也就是说在完全匹配If-Modified-Since和If-None-Match即检查完修改时间和Etag之后,服务器才能返回304。
ETag 还有“强”“弱”之分。
强 ETag 要求资源在字节级别必须完全相符,弱 ETag 在值前有个“W/”标记,只要求资源在语义上没有变化,但内部可能会有部分发生了改变(例如 HTML 里的标签顺序调整,或者多了几个空格)。
还是拿生鲜速递做比喻最容易理解:
你打电话给超市,“我这个西瓜是 3 天前买的,还有最新的吗?”。超市看了一下库存,说:“没有啊,我这里都是 3 天前的。”于是你就知道了,再让超市送货也没用,还是吃冰箱里的西瓜吧。这就是“if-Modified-Since”和“Last-modified”。
但你还是想要最新的,就又打电话:“有不是沙瓤的西瓜吗?”,超市告诉你都是沙瓤的(Match),于是你还是只能吃冰箱里的沙瓤西瓜。这就是“If-None-Match”和“弱 ETag”。
第三次打电话,你说“有不是 8 斤的沙瓤西瓜吗?”,这回超市给了你满意的答复:“有个 10 斤的沙瓤西瓜”。于是,你就扔掉了冰箱里的存货,让超市重新送了一个新的大西瓜。这就是“If-None-Match”和“强 ETag”。
问答
1、Cache 和 Cookie 都是服务器发给客户端并存储的数据,你能比较一下两者的异同吗?
答:
相同点:
都会保存到浏览器中,并可以设置过期时间。
不同点:
- Cookie 会随请求报文发送到服务器,而 Cache 不会,但可能会携带 if-Modified-Since(保存资源的最后修改时间)和 If-None-Match(保存资源唯一标识) 字段来验证资源是否过期。
- Cookie 在浏览器可以通过脚本获取(如果 cookie 没有设置 HttpOnly),Cache 则无法在浏览器中获取(出于安全原因)。
- Cookie 通过响应报文的 Set-Cookie 字段获得,cache缓存的是完整的报文。
- 用途不同。Cookie 常用于身份识别,Cache 则是由浏览器管理,用于节省带宽和加快响应速度。
- cookie的max-age是从客户端收到报文开始计算,cache的则是从服务器发出报文的时候开始计算.
- cookie是方便进行身份识,cache是为了减少网络请求
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人