网页缓存解决方案

8 阅读3分钟

在设置 HTML 页面不使用强缓存(每次都必须回源服务器向协商缓存要结果)时,通常有以下两种方式。最有效、最安全的方法是通过服务器配置(如 Nginx、Apache 或 CDN),因为浏览器最信任这些 HTTP 响应头。

工作原理:

每次打包项目时,工具会根据文件内容生成一个唯一的哈希值(Hash),并把它拼接在文件名里(称为文件指纹):

  • 旧文件:index.a1b2c3.js

  • 新文件(修改了代码):index.x9y8z7.js

缓存配置策略:

  1. HTML 页面:设置 Cache-Control: no-cache(不使用强缓存,每次都回源协商,确保拿到最新的 HTML)。
  2. 静态资源(JS, CSS, 图片) :设置超长强缓存,比如 Cache-Control: max-age=31536000(缓存一年)。

完美的更新闭环:

  • 当你发布新版时,HTML 里面的 <script src="index.x9y8z7.js"> 发生了改变。

  • 用户访问网页,浏览器先去协商更新 HTML(耗时极短,几乎不占流量),拿到了最新的 HTML 源码。

  • 浏览器解析新 HTML,发现需要加载 index.x9y8z7.js

  • 此时本地缓存里只有 index.a1b2c3.js,没有这个新命名的文件。浏览器只能老老实实向服务器下载新文件,并把它强缓存起来。

  • 结果:既利用了强缓存的极致加载速度,又实现了“发布新版,即时更新”的效果。

方式一:最佳实践——在服务器端设置 HTTP 响应头

如果你有控制服务器的权限,应该优先使用这种方法。

1. Nginx 配置

在你的 Nginx 配置文件中,针对 .html.htm 后缀的文件,添加 Cache-Control 头:

Nginx

location ~* .(html|htm)$ {
    # 每次使用前必须向服务器验证数据(即协商缓存)
    add_header Cache-Control "no-cache, no-store, must-revalidate";
    # 兼容旧版本 HTTP/1.0 客户端
    add_header Pragma "no-cache";
    # 设置过期时间为过去,彻底让旧缓存失效
    expires -1;
}

2. Apache 配置 (在 .htaccess 中)

如果你使用的是 Apache 服务器,可以利用 mod_headers 模块:

Apache

<FilesMatch ".(html|htm)$">
    Header set Cache-Control "no-cache, no-store, must-revalidate"
    Header set Pragma "no-cache"
    Header set Expires 0
</FilesMatch>

方式二:前端权宜之计——在 HTML 代码中设置 Meta 标签

如果你无法修改 Nginx 等服务器配置(例如发布在静态托管平台、部分内网环境等),你可以在 HTML 的 <head> 标签中加入以下代码:

HTML

<head>
    <!-- 告诉浏览器每次都必须去服务器校验资源 -->
    <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
    <!-- 兼容旧版的 HTTP 1.0 浏览器 -->
    <meta http-equiv="Pragma" content="no-cache" />
    <!-- 让缓存立刻过期 -->
    <meta http-equiv="Expires" content="0" />
</head>

⚠️ 注意事项(重要):

  1. Meta 标签并不总是 100% 生效。有些浏览器、代理服务器或 CDN 节点在分发流量时,会直接无视 HTML 内部的 Meta 标签,完全以 HTTP 响应头为准。所以它通常作为兜底或备用方案。
  2. 如果你的项目部署在 CDN 上,务必去 CDN 控制台 配置对应的缓存规则,将 HTML 的缓存过期时间设置为 0 或配置为 no-cache

💡 进阶避坑:no-cacheno-store 的区别

在配置时,你可能会看到组合使用的参数,两者的实际效果有些微妙的区别:

  • no-cache:浏览器会缓存这个 HTML,但每次打开页面前,必须带上 ETag 问一句服务器:“我这边的 HTML 变过没有?”如果没变(304),就直接用。这种配置最完美,既实现了更新,又省流量。
  • no-store:浏览器绝对不缓存这个 HTML,每次都必须重新下载整个页面。

通常在前端工程化中(如打包文件名自带哈希值的项目),HTML 建议同时配置 "no-cache, no-store, must-revalidate",确保入口文件永远能拿到最新版,绝不留任何死角。