HTTP状态码304缓存机制

本文详细介绍了HTTP状态码304的缓存机制,包括交互流程、ETag与If-None-Match、Last-Modified与If-Modified-Since的使用,以及HTTP缓存的相关字段如Expires和Cache-Control的作用。通过ETag和Last-Modified的比较,强调了ETag在精确控制缓存方面的重要性。

HTTP 状态码 304 缓存机制

交互流程

客户端第一次请求服务端的某个地址时,服务端会在响应时携带 ETag 与 Last-Modified 响应头,客户端下次再发送同一地址的请求时,会携带 If-None-Match 与 If-Modified-Since 请求头,而 If-None-Match 就是 ETag 的值If-Modified-Since 就是 Last-Modified 的值,这时服务端在接收请求后会获取请求头中的这两个值,然后进行比对,若资源没有更新,则响应 304 状态码,表示请求的资源没有更新,客户端可以从自己的缓存里获取,若资源已更新,则响应 200 状态码,同第一次请求一样,又会在响应时携带新的 ETag 与 Last-Modified 响应头,之后同上逻辑循环

ETag 与 If-None-Match

ETag 是属于 HTTP 1.1 属性,它是由服务器生成返回给前端,说白了,ETag 一般为资源的哈希值,即 ETag 就是服务器生成的一个标记,用来标识资源是否有变化的,且 ETag 的优先级高于 Last-Modified

Last-Modified 与 If-Modified-Since

Last-Modified 与 ETag 类似。不过 Last-Modified 表示响应资源在服务器最后修改时间而已。

与 ETag 相比,不足为:

  1. Last-Modified 标注的最后修改只能精确到秒级,如果某些文件在 1 秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间;
  2. 如果某些文件会被定期生成,但有时内容并没有任何变化,而 Last-Modified 却改变了,导致文件没法使用缓存;
  3. 有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形;

然而,ETag 是服务器自动生成或者由开发者生成的对应资源在服务器端的唯一标识符,能够更加准确的控制缓存。

补充说明:HTTP 缓存机制

HTTP 缓存机制主要在 HTTP 响应头中设定,响应头中相关字段为 Expires、Cache-Control、Last-Modified、Etag。

  • Expires

    • HTTP 1.0 协议中的。简而言之,就是告诉浏览器在约定的这个时间前,可以直接从缓存中获取资源(representations),而无需跑到服务器去获取。
    • Expires 因为是对时间设定的,且时间是 Greenwich Mean Time (GMT),而不是本地时间,所以对时间要求较高。
  • Cache-Control

    • HTTP1.1 协议中的,因为有了它,所以可以忽略上面提到的 Expires。因为 Cache-Control 相对于 Expires 更加具体,细致。
    • 就算同时设置了 Cache-Control 和 Expires,Cache-Control 的优先级也高于 Expires。
    • Cache-Control 响应头中常用字段的具体含义:
      • max-age:用来设置资源(representations)可以被缓存多长时间,单位为秒;
      • s-maxage:和 max-age 是一样的,不过它只针对代理服务器缓存而言;
      • public:指示响应可被任何缓存区缓存;
      • private:只能针对个人用户,而不能被代理服务器缓存;
      • no-cache:强制客户端直接向服务器发送请求,也就是说每次请求都必须向服务器发送。服务器接收到请求,然后判断资源是否变更,是则返回新内容,否则返回304,未变更。这个很容易让人产生误解,使人误以为是响应不被缓存。实际上 Cache-Control: no-cache 是会被缓存的,只不过每次在向客户端(浏览器)提供响应数据时,缓存都要向服务器评估缓存响应的有效性。
      • no-store:禁止一切缓存(这个才是响应不被缓存的意思)。
<think>好的,用户想了解HTTP状态码304的含义。首先,我需要确认自己对这个状态码的理解是否正确。HTTP 304属于3xx重定向类别吗?不,3xx主要是重定向相关的,比如301永久移动,302临时移动。而304应该是关于缓存的。 我记得304状态码是“Not Modified”,也就是未修改。当客户端发送请求时,如果资源自上次请求后没有更改,服务器会返回304,告诉客户端可以使用本地缓存的版本。这样可以减少数据传输,节省带宽,提高性能。 接下来,需要验证这个理解是否正确。可以参考RFC文档,比如RFC 7232中的条件请求部分。304响应确实是在客户端提供了如If-Modified-Since或If-None-Match头部的情况下,服务器验证资源未修改时返回的。这样客户端就不需要重新下载资源,直接从缓存加载。 然后,用户可能还想知道304的应用场景和好处。比如浏览器缓存静态资源如图片、CSS、JS文件,通过304减少服务器负担,加快页面加载。另外,304和200 OK的区别在于,304没有响应体,只返回头部,节省流量。 可能还需要提到相关的HTTP头部,比如Last-Modified和ETag,这些是服务器用来验证资源是否变化的机制。客户端在后续请求中携带这些信息,服务器进行比较后决定返回304还是200。 用户的问题可能还涉及304与其他状态码的区别,比如200、404。304属于成功状态码,但表示资源未修改,而404是资源不存在。确保解释清楚这些区别。 另外,是否有常见的误解需要澄清?比如,304是否属于错误码?其实它是成功响应的一部分,指示客户端使用缓存,而不是错误。这可能会让用户更清楚它的作用。 最后,是否需要举例说明?比如浏览器第一次请求一个图片,服务器返回200和Last-Modified时间。下次请求时,浏览器带上If-Modified-Since头部,如果图片未修改,服务器返回304,浏览器使用缓存图片。 总结回答的结构:先定义304状态码,解释其用途,工作机制,应用场景,相关HTTP头部,与其他状态码的区别,以及实际例子。同时,引用相关RFC文档或权威资料来支持解释,比如RFC 7232[^1]。</think>### HTTP状态码304的含义 HTTP状态码304(Not Modified)属于**客户端重定向响应**类别,用于指示客户端可以使用本地缓存的资源副本,因为服务器端资源自上次请求以来未被修改。 #### 工作机制 1. **条件请求**:客户端需在请求头中携带验证信息 - `If-Modified-Since`:基于时间戳验证 - `If-None-Match`:基于ETag指纹验证 2. **服务器验证**:服务器检查资源是否满足条件 3. **响应决策**: - 资源未更新 → 返回304(无响应体) - 资源已更新 → 返回200 + 新内容 #### 核心价值 $$ 传输数据量 = 0 $$ 通过避免重复传输未修改资源,显著降低带宽消耗,提升网页加载速度,适用于静态资源缓存场景[^2]。 #### 实际应用示例 ```http # 首次请求 GET /logo.jpg Host: example.com # 服务器响应 HTTP/1.1 200 OK Last-Modified: Wed, 21 Oct 2022 07:28:00 GMT ETag: "33a64df551425fcc55e4d42a148795d9" # 后续请求 GET /logo.jpg Host: example.com If-Modified-Since: Wed, 21 Oct 2022 07:28:00 GMT If-None-Match: "33a64df551425fcc55e4d42a148795d9" # 服务器响应 HTTP/1.1 304 Not Modified ``` #### 对比其他状态码 | 状态码 | 缓存使用 | 响应体 | |--------|----------|--------| | 200 OK | 不强制 | 有 | | 304 | 必须使用 | 无 | | 404 | - | 有 |
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值