云计算百科
云计算领域专业知识百科平台

谈谈 HTTP 的缓存机制,服务器如何判断缓存是否过期?

HTTP 缓存=“先看本地冰箱够不够新鲜(强缓存);不够再打电话问超市要不要换(协商缓存)”。服务器判断是否过期靠 Expires / Cache-Control 给出的“保质期”,以及 ETag / Last-Modified 做“指纹校验”。

一、缓存流程图解(关键决策链)

二、服务器判断缓存过期的核心机制

1. 强缓存阶段(无需询问服务器)
  • Cache-Control 响应头(优先级最高):

    Cache-Control: max-age=3600 // 资源有效期3600秒(1小时)

    • max-age=[秒]:资源有效期(从请求时间开始计算)

    • s-maxage=[秒]:仅对公共代理缓存有效(CDN专用)

    • no-store:禁止任何缓存(敏感数据场景)

    • no-cache:跳过强缓存,直接进入协商缓存

    • public:允许任何缓存方(浏览器/CDN)存储

    • private:仅允许用户浏览器缓存(禁止CDN)

  • Expires 响应头(HTTP/1.0遗留):

    Expires: Wed, 24 Jul 2024 08:30:00 GMT // 绝对过期时间

    • 缺陷:依赖客户端时钟同步,已被 Cache-Control 取代

2. 协商缓存阶段(需向服务器验证)

当强缓存失效时,客户端携带验证头发起条件请求:

  • Last-Modified + If-Modified-Since

    # 响应头(服务器返回)
    Last-Modified: Wed, 17 Jul 2024 12:00:00 GMT

    # 请求头(客户端后续携带)
    If-Modified-Since: Wed, 17 Jul 2024 12:00:00 GMT

    • 服务器对比当前资源的修改时间

    • 问题:1秒精度不足,文件内容不变但修改时间可能变化

  • ETag + If-None-Match(优先级更高)

    # 响应头(服务器返回)
    ETag: "33a64df551425fcc55e4d42a148795d9"

    # 请求头(客户端后续携带)
    If-None-Match: "33a64df551425fcc55e4d42a148795d9"

    • ETag 是资源内容的哈希值(如MD5)

    • 内容变化时 ETag 必变,精确判断内容变更

    • 分强弱验证:

      • 强ETag:字节级匹配("xyz")

      • 弱ETag:内容语义匹配(W/"xyz",前缀 W/)

三、缓存决策关键头组合示例

场景1:静态资源(JS/CSS)长期缓存

HTTP/1.1 200 OK
Cache-Control: public, max-age=31536000 // 1年有效期
ETag: "fd562e25w5e41"

场景2:用户私密数据

HTTP/1.1 200 OK
Cache-Control: private, no-cache // 仅浏览器缓存且跳过强缓存

场景3:频繁变化的API数据

HTTP/1.1 200 OK
Cache-Control: no-cache           // 强制每次协商验证
ETag: "a3f5gd8e9k2"


四、缓存生效全流程演示

  • 首次请求

    GET /app.js HTTP/1.1 HTTP/1.1 200 OK
    Cache-Control: max-age=3600
    ETag: "abc123"
    Last-Modified: Wed, 24 Jul 2024 00:00:00 GMT

  • 60分钟内再次请求 → 直接读浏览器缓存(不发送请求)

  • 60分钟后请求(强缓存过期)

    GET /app.js HTTP/1.1
    If-Modified-Since: Wed, 24 Jul 2024 00:00:00 GMT
    If-None-Match: "abc123"

    • 若资源未变 → 返回 304 Not Modified,重置缓存有效期

    • 若资源变化 → 返回 200 OK 和新内容

  • 五、缓存陷阱与解决方案

    问题原因解决方案
    用户看不到更新 强缓存未过期 文件名添加哈希:app.a3c4.js
    CDN不更新 源服务器未刷新CDN缓存 添加 Cache-Control: s-maxage=0
    登录态与缓存冲突 缓存了用户私有数据 设置 Cache-Control: private
    弱网环境缓存失效 未正确配置 Cache-Control 至少设置 max-age=600(10分钟)

    六、最佳实践策略

  • 静态资源

    • 文件名带内容哈希:/css/style.a3d8.css

    • 设置超长缓存:Cache-Control: public, max-age=31536000

  • 动态API

    • 短缓存 + 协商缓存:

      Cache-Control: no-cache, max-age=600 // 10分钟强缓存 + 强制验证
      ETag: "x138de9"

  • HTML入口文件

    • 禁止缓存(确保版本更新):

      Cache-Control: no-store, no-cache, must-revalidate

  • 📊 性能收益:合理缓存可使重复访问速度提升 300%+(HTTP Archive 数据)


    七、调试技巧(Chrome DevTools)

  • Network面板

    • 尺寸列显示 (from disk cache) 表示强缓存命中

    • 304 状态码表示协商缓存生效

  • 查看完整缓存头 https://example.com/chrome-cache-headers.png

  • 强制刷新

    • Ctrl+F5:忽略强缓存(带 Cache-Control: no-cache 头)

    • Ctrl+Shift+R:忽略所有缓存和Service Worker

  • 缓存配置口诀:

    静态资源长缓存,动态数据短校验, 哈希指纹破更新,HTML入口永不存。

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 谈谈 HTTP 的缓存机制,服务器如何判断缓存是否过期?
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!