强缓存和协商缓存分别是什么?

浏览器缓存分为强缓存和协商缓存,两者有两个比较明显的区别:

  1. 如果浏览器命中强缓存,则不需要给服务器发送请求,尽管会返回请求状态码200(from cache);
  2. 协商缓存有服务器决定是否使用缓存,客户端和服务器之间会发生一次通讯,如果命中协商缓存,则服务器返回304。

强缓存

强缓存是根据返回头中的Expires 或者 Cache-Control 两个字段来控制的,都是表示资源的缓存有效时间。

  • Expires是HTTP1.0的规范,返回一个GMT格式的时间字符串,如Expires:Mon,18 Oct 2022 23:59:59 GMT ,表示资源失效的时间,如果当前的时间戳在这个时间之前,则命中强缓存。问题在于服务器和客户端之间的绝对时间偏差可能较大,导致缓存混乱。
  • Cache-Control是HTTP1.1的规范,一般用max-age字段来表示相对时间,比如 Cache-Control:max-age=3600 代表资源的有效期是 3600 秒。并且返回头中的 Date 表示消息发送的时间,表示当前资源在 Date ~ Date +3600s 这段时间里都是有效的。

如果 Cache-Control与 Expires 同时存在的话, Cache-Control 的优先级高于 Expires 。

协商缓存

协商缓存是由服务器来确定缓存资源是否可用。

  • Last-Modified/If-Modified-Since 二者的值都是 GMT 格式的时间字符串,Last-Modified标记了文件最后的修改时间,然后在下一次请求时请求头带上If-Modified-Since,其值为本地保存的Last-Modified,告诉服务器我本地缓存最后的修改时间,服务器如果判断文件未修改,则命中协商缓存,返回304 Not Modified状态码,浏览器就不再请求资源,直接使用本底的缓存;如果文件修改,则返回资源内容,新的 Last-Modified 会在 response header 返回,并在下次请求之前更新本地缓存的 Last-Modified,下次请求时,If-Modified-Since会启用更新后的 Last-Modified。缺点是最小判断步长为1秒,无法判断1秒内的多次变化。
  • Etag/If-None-Match,对于每一个文件,服务器根据文件本身算出一个哈希值(一般来说是哈希结构)并通过 Etag字段返回给浏览器,然后下一次请求后请求头带上 If-None-Match 字段,服务器会通过比较两者是否一致来判定文件内容是否被改变。与 Last-Modified 不一样的是,当服务器返回 304 Not Modified 的响应时,由于在服务器上ETag 重新计算过,response header中还会把这个 ETag 返回,即使这个 ETag 跟之前的没有变化。缺点是计算Etag值有性能损耗。
### HTTP 缓存机制概述 HTTP 协议提供了多种缓存控制方法来优化网络性能并减少服务器负载。主要分为两种类型的缓存策略:强缓存协商缓存。 #### 强缓存 (Strong Cache) 当浏览器请求资源时,如果该资源被标记为可由客户端本地存储,则可以直接从浏览器缓存读取而无需再次向服务器发起请求。这通过响应头中的特定字段实现: - `Cache-Control` `Expires` 是两个用于定义资源有效期的关键字。 - 如果设置了 `Cache-Control: max-age=<seconds>` 或者存在有效的 `Expires` 头部,那么在这段时间内,浏览器会认为此内容是最新的,并不会发送任何额外的验证请求到源站获取最新版本的内容[^1]。 这种模式极大地提高了访问速度并且节省带宽消耗,因为整个过程完全发生在用户的设备上而不涉及外部通信。 ```http GET /image.png HTTP/1.1 Host: example.com HTTP/1.1 200 OK Date: Mon, 27 Jul 2009 12:28:53 GMT Server: Apache Last-Modified: Wed, 22 Jul 2009 19:15:56 GMT ETag: "34aa387-d-1e3fbc80" Accept-Ranges: bytes Content-Length: 51 Vary: Accept-Encoding Content-Type: image/png Cache-Control: public, max-age=31536000 ``` #### 协商缓存 (Negotiated Cache) 对于那些可能频繁更新或需要更精确控制其新鲜度状态的对象来说,采用的是基于条件式的重新验证方式——即所谓的“协商缓存”。在这种情况下,即使有可用的本地副本,在每次加载页面之前都会先询问原始服务器确认这些数据是否仍然有效。 常用的方法包括利用如下头部信息来进行比较判断: - `If-None-Match`: 客户端携带 ETag 值给服务端对比; - `If-Modified-Since`: 使用最后修改时间戳作为参照标准; 一旦发现当前保存的数据已经过期或是发生了变化,就会返回完整的实体主体以及相应的元数据供前端刷新显示;反之则仅需回应一个简单的 `304 Not Modified` 状态码告知对方可以继续沿用旧有的记录即可[^2]。 ```http GET /index.html HTTP/1.1 Host: www.example.org If-None-Match: "33a6c576aeedfc1eace167b9b3f2dcb3" HTTP/1.1 304 Not Modified Date: Tue, 28 Jul 2009 12:28:53 GMT Server: Apache Etag: "33a6c576aeedfc1eace167b9b3f2dcb3" ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值