欢迎光临
我们一直在努力

Http 缓存技术

核心目的:减少网络请求、降低延迟、减轻服务器压力、节省带宽。 分为两大类:强缓存、协商缓存。

强缓存:不用发请求到服务器,直接拿本地缓存。 协商缓存:必须发请求给服务器,服务器判断缓存是否可用。

一、强缓存(不访问服务器,200 OK (from disk cache /from memory cache))

响应头控制,浏览器直接本地读取,不产生 HTTP 请求。

  • Expires(HTTP1.0,已过时)
  • Expires: Wed, 10 Sep 2026 10:00:00 GMT

    • 绝对时间,GMT 格式;受客户端系统时间影响,时间错乱会失效。
  • Cache‑Control(HTTP1.1,主流,优先级高于 Expires)
  • Cache-Control: max-age=86400

    • max‑age=86400:缓存有效时长,单位秒。从响应返回那一刻开始计时。

    常用指令:

    指令含义
    max‑age=N 强缓存有效期 N 秒
    no‑cache 不使用强缓存,强制走协商缓存
    no‑store 完全不缓存,什么都不存
    public 代理服务器也可以缓存(CDN)
    private 仅浏览器客户端缓存,CDN 不缓存

    区分重点:

    • no‑cache:不是不缓存,每次都要问服务器(协商缓存)
    • no‑store:禁止一切缓存,本地不留副本

    二、协商缓存(一定发请求到服务器,304 Not Modified)

    浏览器带上标识,服务器对比资源有没有修改。

    • 未修改:返回304 Not Modified,没有响应 body,浏览器直接读本地缓存
    • 修改:返回200 OK,返回新资源

    两套机制:

    1. Last‑Modified / If‑Modified‑Since(基于修改时间)

    1)服务器响应头返回:

    Last‑Modified: Tue, 08 Sep 2026 08:00:00 GMT

    资源最后修改时间。

    2)下次请求,浏览器自动带上请求头:

    If‑Modified‑Since: Tue, 08 Sep 2026 08:00:00 GMT

    服务器对比文件修改时间:

    • 时间没变 → 返回 304
    • 文件更新 → 返回 200 + 新内容

    缺点:

  • 时间精度只能到秒;1 秒内多次修改识别不出。
  • 文件内容没变,但服务器修改了修改时间,也会重新下载。
  • 2. ETag / If‑None‑Match(基于内容哈希,优先级高于时间)

    1)服务器返回资源哈希标识

    ETag: "abc123xxxx"

    ETag:资源内容的摘要哈希,内容一变 ETag 一定变。

    2)浏览器下次请求带上

    If‑None‑Match: "abc123xxxx"

    服务器对比 ETag:

    • 匹配:304
    • 不匹配:200 返回新资源

    ETag 解决 Last‑Modified 的秒级精度缺陷。

    执行顺序(浏览器真实流程)

  • 看强缓存 Cache‑Control(max‑age) / Expires
    • ✅没过期:直接本地读取,from cache,不发 http 请求
    • ❌过期了 → 进入协商缓存
  • 发送 HTTP 请求,带上 If‑None‑Match(ETag)、If‑Modified‑Since
    • 服务器校验 ETag 优先,再校验修改时间
    • 资源未改动 → 返回 304,浏览器用本地缓存
    • 资源改动 → 返回 200,返回新资源,更新本地缓存副本
  • 内存缓存 vs 磁盘缓存

    • memory cache(内存):页面打开时存在内存,关闭标签页就释放;优先级高。
    • disk cache(硬盘):写入硬盘,关闭浏览器还在。

    JS、CSS、图片优先放内存;大文件进入磁盘缓存。

    CDN 缓存

    CDN 本质就是代理服务器缓存,遵循 HTTP 缓存头Cache‑Control。 静态资源放 CDN,设置合理 max‑age; 资源更新:修改资源文件名(加哈希后缀 app.abc123.js),绕过旧缓存。

    HTTP 缓存默认开启吗?

    ✅浏览器端:默认开启 HTTP 缓存(强缓存 + 协商缓存全部默认打开) ❌后端服务器不会自动给你加缓存响应头,缓存生效,要看服务器返回的响应头

    1、浏览器行为(客户端)

    浏览器本身默认就会做缓存:磁盘缓存、内存缓存。 只要服务端返回了 Cache‑Control / Expires / Last‑Modified / ETag,浏览器就自动执行缓存逻辑,不需要前端写任何代码。

    如果服务器什么缓存头都不返回: 浏览器依旧会试探性缓存(启发式缓存),不会完全不缓存,只是缓存时间不可控,不推荐靠这个。

    启发式缓存

    当响应既没有Cache‑Control:max‑age,也没有Expires。 浏览器拿 Date(响应时间) 和 Last‑Modified,自己算一个缓存时间(大概是差值的 10%)做短期强缓存。

    不可控,业务不能依赖这个机制。

    2、不同服务器默认行为

    ① Nginx、Apache(静态资源:图片 /js/css)

    默认:

    • 返回 Last‑Modified、ETag 👉 协商缓存默认生效
    • 但是不会默认给你加 max‑age 强缓存,强缓存要手动配置。

    也就是说 Nginx 静态文件:默认走协商缓存,会发请求,可能返回 304;不会直接 from disk cache。

    ② SpringBoot(Java 后端)

  • Controller 接口、动态接口 SpringBoot默认不会输出任何缓存头。 没有 Cache‑Control、ETag、Last‑Modified。
  • 浏览器不会做有意义的缓存,每次都请求 200。 想要缓存,需要手动配置响应头,或者用@CacheControl,或者 WebMvc 配置。

  • SpringBoot 的静态资源(resources/static 下面的图片 js) ✅默认开启 ETag + Last‑Modified(协商缓存),也就是会出现 304。 ❌默认不开启强缓存 max‑age,需要手动设置。
  • 3、怎么关闭浏览器缓存

  • F12 → Network → ✅Disable cache(仅开发者工具生效,真实用户无效)
  • 请求头添加:Cache‑Control: no‑cache,Pragma:no‑cache
  • url 加随机参数 xxx.js?t=123456,绕过缓存
  • 4、总结

    浏览器默认开启 HTTP 缓存能力; 协商缓存 (ETag/Last‑Modified) Nginx、SpringBoot 静态资源默认会返回; 强缓存 max‑age 不会默认开启,必须后端手动配置响应头; 如果服务端完全没有缓存头,浏览器会使用启发式缓存,行为不可预测。

    补充示例 SpringBoot 开启缓存头

    // 给响应设置强缓存,1天
    response.setHeader("Cache‑Control","public,max‑age=86400");

    生产实践: JS/CSS 图片 → Nginx 配置 max‑age 做大强缓存; HTML 页面一般不做强缓存,用 no‑cache 走协商缓存。

    赞(0)
    未经允许不得转载:171主机测评 » Http 缓存技术
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址