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-SinceIf-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-SinceIf-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-ModifiedETag 头部,客户端在后续请求中使用这些头部进行条件请求。如果内容未被修改,服务器返回 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-SinceIf-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-ModifiedETag 头部,以便客户端可以进行条件请求。例如:

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

(二)合理配置缓存策略

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

(三)测试缓存行为

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

七、总结

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

八、参考文献

  • 1\] MDN Web Docs. HTTP Status Codes. \[Online\]. Available: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status

相关推荐
微爱帮监所写信寄信21 小时前
微爱帮监狱写信寄信工具服务器【Linux篇章】再续:TCP协议——用技术隐喻重构网络世界的底层逻辑
linux·服务器·开发语言·网络·网络协议·小程序·监狱寄信
发光小北1 天前
SG-LORA_2024 系列(多信号转 LORA 无线中继器)特点与功能介绍
网络协议
牛魔王_11 天前
ASP.NET 超时机制分析
后端·http·asp.net·超时·代码
heartbeat..1 天前
网络通信核心知识全解析:模型、协议与 TCP 机制
java·网络·网络协议·tcp/ip
一只小鱼儿吖1 天前
从代理ip的底层逻辑探讨下如何选择代理ip商。
网络·python·网络协议·tcp/ip
啊阿狸不会拉杆1 天前
GLM-4.7 与 MiniMax M2.1 模型使用与配置指南
状态模式·api
异界蜉蝣1 天前
数组的「静态提升」:是否值得?如何实现?
状态模式
教练、我想打篮球1 天前
123 safari 浏览器中下载 URLEncoder.encode 的中文名称的文件, safari 未进行解码, 其他浏览器正常
前端·http·safari
鲨莎分不晴1 天前
深入理解 UDP:大道至简的传输层基石
网络·网络协议·udp
微爱帮监所写信寄信1 天前
微爱帮监狱寄信写信小程序:深入理解JavaScript中的Symbol特性
开发语言·javascript·网络协议·小程序·监狱寄信·微爱帮