浏览器请求旧css是因为未使用内容哈希,导致路径不变而缓存未更新;解决方法是用contenthash生成带指纹的文件名,并由构建工具自动替换html中link标签的href。

为什么 link 标签里加了 href 但浏览器还是请求旧 CSS?
因为没做内容哈希,浏览器缓存的是文件路径,不是文件内容。只要路径不变(比如 style.css),哪怕你改了代码、重新构建,用户本地可能还在用上一版的缓存。
解决办法是让文件名带上内容指纹——比如把 style.css 变成 style.abc123.css,每次内容变,哈希就变,路径就变,浏览器自然请求新文件。
- Webpack 默认用
[contenthash],Vite 用[hash](实际也是内容哈希),Rollup 用[hash]或[digest:hex] - 别用
[hash](构建 hash)代替[contenthash]:整个构建变了它就变,哪怕只改一行 CSS,JS 文件名也跟着刷新,破坏长期缓存 - HTML 中的
<link href="style.css">必须由构建工具自动替换成带哈希的路径,手写或后端拼接容易出错
Webpack 中怎么配 MiniCssExtractPlugin 输出带哈希的 CSS?
它负责把 CSS 从 JS 里抽出来单独成文件,但默认输出名不带哈希,得显式配置。
关键在 filename 和 chunkFilename 两个选项,且必须用 [contenthash],不是 [hash]。
立即学习“前端免费学习笔记(深入)”;
-
filename: 'css/[name].[contenthash:8].css'—— 对应入口 CSS -
chunkFilename: 'css/[name].[contenthash:8].css'—— 对应动态 import 的 CSS - 如果用了
output.publicPath,确保它以/结尾,否则生成的href可能漏前缀 - 开发环境别开这个插件(用
style-loader),否则热更新失效或报Refused to apply inline style
Vite 构建后 HTML 里的 CSS 路径没更新?
Vite 默认已做内容哈希,但如果你手动写了 <link rel="stylesheet" href="/style.css">,它不会被重写——Vite 只处理通过 import './style.css' 引入的样式。
- 所有 CSS 必须走 JS 模块导入(
import),才能进构建流程并被重写 - 不要在
index.html里硬编码href,除非你用vite-plugin-html手动注入 - 检查构建产物中
index.html的href值,应该是类似/assets/index.9f3a7b2e.css,而不是/style.css - 如果用了
base配置(如base: '/myapp/'),哈希文件路径会自动加前缀,但得确保 CDN 或服务器能正确映射
CDN 缓存和浏览器缓存怎么配合才不打架?
CDN 通常按 URL 缓存,浏览器也一样。所以只要文件名带内容哈希,两者就能一致刷新;但若 CDN 设置了强制缓存 1 年,而你忘了清缓存,用户仍可能拿到旧文件。
- 构建后上传到 CDN 时,建议用带版本标识的路径(如
/v1.2.0/assets/...),或上传后主动调 API 清除对应路径缓存 - 避免对哈希文件设过长
Cache-Control: max-age=31536000,虽然安全,但 CDN 层万一没及时刷新,问题难排查 - 上线后快速验证:打开 DevTools → Network → 刷新,看 CSS 请求状态码是不是
200(不是304或from disk cache),再比对响应头ETag或文件内容是否最新
最麻烦的不是配错哈希,而是 HTML 和 CSS 文件缓存策略不一致——比如 HTML 设了 no-cache,CSS 却缓存一年,结果 HTML 拿到了新版,但引用的还是旧哈希路径,404 就来了。










