HTTP 状态码 304:未修改(Not Modified)的深度解析

🤍 前端开发工程师、技术日更博主、已过CET6

🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1

🕠 牛客 高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》、《前端求职突破计划》

🍚 蓝桥云课 签约作者、上架课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入门到实战全面掌握 uni-app》

文章目录

一、引言

在现代 Web 开发中,性能优化和资源管理是至关重要的。HTTP 协议为此提供了多种机制,其中缓存机制是提高性能和减少服务器负载的关键技术之一。HTTP 状态码 304(Not Modified)正是缓存机制中的一个重要组成部分。本文将深入探讨 HTTP 状态码 304 的含义、工作原理以及如何在实际开发中利用它来优化性能。

二、HTTP 状态码 304 的定义

(一)什么是 HTTP 状态码 304?

HTTP 状态码 304(Not Modified)表示客户端发送了一个带有条件请求的 GET 请求(例如,带有 If-Modified-Since 或 If-None-Match 头部),但服务器检查后发现资源自上次请求以来未被修改。因此,服务器不需要发送完整的资源内容,只需返回 304 状态码即可。

(二)304 状态码的作用

  1. 减少不必要的数据传输:如果资源未被修改,服务器不需要重新发送完整的资源内容,从而节省带宽和减少响应时间。
  2. 提高性能:通过利用缓存机制,客户端可以直接使用本地缓存的资源,而无需等待服务器的完整响应。
  3. 减轻服务器负载:服务器不需要处理完整的资源请求,从而可以处理更多的并发请求。

三、304 状态码的工作原理

(一)条件请求

客户端可以通过以下两种方式发送条件请求:

  1. If-Modified-Since:客户端指定一个时间戳,表示它希望获取自该时间戳以来被修改的资源。如果资源自该时间戳以来未被修改,服务器将返回 304 状态码。

    http 复制代码
    GET /example.html HTTP/1.1
    Host: example.com
    If-Modified-Since: Wed, 21 Oct 2023 07:28:00 GMT
  2. If-None-Match:客户端指定一个 ETag(实体标签),表示它希望获取与该 ETag 不匹配的资源。如果资源的 ETag 与客户端指定的 ETag 相同,服务器将返回 304 状态码。

    http 复制代码
    GET /example.html HTTP/1.1
    Host: example.com
    If-None-Match: "1234567890abcdef"

(二)服务器响应

服务器接收到带有条件请求的 GET 请求后,会检查资源是否被修改:

  1. 如果资源自指定时间戳以来未被修改(If-Modified-Since),或者资源的 ETag 与客户端指定的 ETag 相同(If-None-Match),服务器将返回 304 状态码。

    http 复制代码
    HTTP/1.1 304 Not Modified
  2. 如果资源被修改,服务器将返回完整的资源内容,状态码为 200(OK)。

    http 复制代码
    HTTP/1.1 200 OK
    Content-Type: text/html; charset=UTF-8
    Content-Length: 1234
    
    <html>...</html>

(三)客户端处理

客户端接收到 304 状态码后,会直接使用本地缓存的资源,而无需重新解析响应体。这大大减少了数据传输量和响应时间。

四、304 状态码的使用场景

(一)静态资源缓存

对于静态资源(如图片、CSS 文件、JavaScript 文件等),304 状态码可以显著提高性能。客户端在首次请求资源后,会缓存该资源,并在后续请求中使用条件请求头(If-Modified-Since 或 If-None-Match)检查资源是否被修改。如果资源未被修改,服务器返回 304 状态码,客户端直接使用缓存的资源。

示例:
  1. 首次请求:

    http 复制代码
    GET /styles.css HTTP/1.1
    Host: example.com

    服务器响应:

    http 复制代码
    HTTP/1.1 200 OK
    Content-Type: text/css; charset=UTF-8
    Content-Length: 1234
    Last-Modified: Wed, 21 Oct 2023 07:28:00 GMT
    ETag: "1234567890abcdef"
    
    body { ... }
  2. 后续请求:

    http 复制代码
    GET /styles.css HTTP/1.1
    Host: example.com
    If-Modified-Since: Wed, 21 Oct 2023 07:28:00 GMT
    If-None-Match: "1234567890abcdef"

    服务器响应:

    http 复制代码
    HTTP/1.1 304 Not Modified

(二)动态内容缓存

对于动态生成的内容(如 HTML 页面),304 状态码同样可以提高性能。服务器可以在响应中包含 Last-Modified 或 ETag 头部,客户端在后续请求中使用这些头部进行条件请求。如果内容未被修改,服务器返回 304 状态码,客户端直接使用缓存的内容。

示例:
  1. 首次请求:

    http 复制代码
    GET /index.html HTTP/1.1
    Host: example.com

    服务器响应:

    http 复制代码
    HTTP/1.1 200 OK
    Content-Type: text/html; charset=UTF-8
    Content-Length: 1234
    Last-Modified: Wed, 21 Oct 2023 07:28:00 GMT
    ETag: "1234567890abcdef"
    
    <html>...</html>
  2. 后续请求:

    http 复制代码
    GET /index.html HTTP/1.1
    Host: example.com
    If-Modified-Since: Wed, 21 Oct 2023 07:28:00 GMT
    If-None-Match: "1234567890abcdef"

    服务器响应:

    http 复制代码
    HTTP/1.1 304 Not Modified

(三)API 缓存

在 RESTful API 中,304 状态码可以用于优化性能。客户端在请求资源时,可以使用 If-Modified-Since 或 If-None-Match 头部检查资源是否被修改。如果资源未被修改,服务器返回 304 状态码,客户端直接使用缓存的资源。

示例:
  1. 首次请求:

    http 复制代码
    GET /api/users/123 HTTP/1.1
    Host: example.com

    服务器响应:

    http 复制代码
    HTTP/1.1 200 OK
    Content-Type: application/json
    Content-Length: 1234
    Last-Modified: Wed, 21 Oct 2023 07:28:00 GMT
    ETag: "1234567890abcdef"
    
    {
      "id": 123,
      "name": "John Doe",
      "email": "john.doe@example.com"
    }
  2. 后续请求:

    http 复制代码
    GET /api/users/123 HTTP/1.1
    Host: example.com
    If-Modified-Since: Wed, 21 Oct 2023 07:28:00 GMT
    If-None-Match: "1234567890abcdef"

    服务器响应:

    http 复制代码
    HTTP/1.1 304 Not Modified

五、304 状态码的优势

(一)性能优化

通过减少不必要的数据传输,304 状态码显著提高了客户端和服务器之间的通信效率。客户端可以直接使用本地缓存的资源,而无需等待服务器的完整响应,从而减少了响应时间和带宽消耗。

(二)减轻服务器负载

服务器不需要处理完整的资源请求,从而可以处理更多的并发请求。这有助于提高服务器的性能和可靠性,尤其是在高流量场景下。

(三)提高用户体验

通过利用缓存机制,用户可以更快地获取资源,从而提高了用户体验。用户无需等待完整的资源加载,页面加载速度更快。

六、最佳实践

(一)正确设置缓存头部

服务器应该在响应中正确设置 Last-Modified 和 ETag 头部,以便客户端可以进行条件请求。例如:

http 复制代码
Last-Modified: Wed, 21 Oct 2023 07:28:00 GMT
ETag: "1234567890abcdef"

(二)合理配置缓存策略

根据资源的性质和更新频率,合理配置缓存策略。例如,对于静态资源,可以设置较长的缓存时间;对于动态内容,可以设置较短的缓存时间。

(三)测试缓存行为

在部署缓存机制后,务必测试缓存行为,确保客户端能够正确地使用缓存资源。可以使用浏览器的开发者工具或网络抓包工具(如 Wireshark)来检查缓存行为。

七、总结

HTTP 状态码 304(Not Modified)是缓存机制中的一个重要组成部分。它通过减少不必要的数据传输,显著提高了客户端和服务器之间的通信效率。304 状态码适用于静态资源缓存、动态内容缓存和 API 缓存等多种场景。开发者可以通过正确设置缓存头部、合理配置缓存策略和测试缓存行为,充分利用 304 状态码来优化性能和提高用户体验。

八、参考文献

相关推荐
码匠许师傅18 小时前
【C++三方组件】cpp-httplib:一个头文件起 HTTP 服务
开发语言·c++·http
不会就选b19 小时前
Linux之应用层协议HTTP(二)
网络·网络协议·http
hasty19 小时前
只监听本机为何仍需鉴权?Cline Hub 的 WebSocket 信任边界解析
网络·websocket·网络协议
牧瀬クリスだ1 天前
Spring统一功能处理
java·spring boot·spring·状态模式
2501_937860941 天前
下篇:网络层、数据链路层与应用层:IP、NAT、ARP、DNS 一网打尽
网络·网络协议·tcp/ip
ITxiaobing20231 天前
IP 定位服务怎么选:第三方认可、实测精度和合规边界不是一回事
网络·网络协议·tcp/ip
VidDown1 天前
从视频画面里提取文字:OCR、文字检测与结构化输出
python·网络协议·ocr·音视频·视频编解码·视频
阿钱真强道1 天前
12 嵌入式操作系统 | UDP 服务器编程
服务器·网络协议·udp
VidDown1 天前
文件没问题但网页播不了:播放器接入实战与那些“环境问题
python·网络协议·音视频·视频编解码·视频
liangshanbo12151 天前
面试题:HTTP/2有哪些升级
网络·网络协议·http