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

相关推荐
数字芯片实验室1 小时前
IP验证最终回归到时序级建模
网络·网络协议·tcp/ip·fpga开发
掘根4 小时前
【jsonRpc项目】常用的零碎功能接口实现
网络协议·http
googleccsdn5 小时前
ENSP Pro Lab笔记:配置BGP EVPN VXLAN双栈(2)
网络·笔记·网络协议
陌路206 小时前
RPC分布式通信(3)--RPC基础框架接口
分布式·网络协议·rpc
Dreamboat_LX7 小时前
websocket-sockjs-stomp
网络·websocket·网络协议
ps酷教程8 小时前
HttpPostRequestEncoder使用示例
http·netty
txinyu的博客9 小时前
TCP的可靠性问题
网络·网络协议·tcp/ip
陌路209 小时前
RPC分布式通信(1)--分布式通信讲解
分布式·网络协议·rpc
php_kevlin10 小时前
websocket实现站内信
android·websocket·网络协议
2401_8658548810 小时前
ssl证书使用中可能会遇到的问题
网络·网络协议·ssl