加?v=能绕过CSS缓存,因浏览器依据完整URL判断缓存,URL变化即触发新请求;服务端无需解析该参数,Nginx等默认忽略查询字符串,仅按路径匹配文件。

直接改 style.css 内容却没生效?不是代码写错了,是浏览器死死攥着旧缓存不放——link 标签的 URL 没变,它就绝不会发新请求。
为什么加 ?v=xxx 能绕过缓存
浏览器把 style.css 和 style.css?v=20240520 当作两个完全不同的资源。只要 URL 变了,缓存就失效,必须重新拉取。
-
v是参数名,不是关键字;用ver、ts甚至hash都行,但别用random类动态值(比如?t=<script>Math.random()</script>),会彻底废掉缓存复用 - 值推荐用构建时间戳(如
202607071530)或 Git commit hash(如abc123),避免手动维护出错 - 服务端无需任何改动——查询参数不影响文件路径解析,Nginx/Apache 默认就忽略它
Webpack/Vite 怎么自动注入哈希而不是手写 v=
手写版本号容易漏改、错发,构建工具能保证“内容一变,URL 就变”,才是生产环境该用的方式。
- Webpack:必须用
mini-css-extract-plugin提取 CSS,output.filename里含[contenthash](如main.[contenthash:8].css),再配html-webpack-plugin自动写入 HTML - Vite:在
vite.config.ts中设置build.rollupOptions.output.assetFileNames为"assets/[name].[hash].css";若开启cssCodeSplit,还得同步配置entryFileNames和chunkFileNames - 关键陷阱:HTML 里硬写的
<link href="style.css">不会被构建工具处理——删掉它,改用 JSimport './style.css',让构建链路全程接管
CDN 或 Nginx 忽略了 ?v= 怎么办
本地测得好好的,上线后失效?大概率是 CDN 或反向代理把带查询参数的请求当成同一个资源缓存了。
立即学习“前端免费学习笔记(深入)”;
- Nginx 检查
proxy_cache_key是否包含$args,正确写法类似:proxy_cache_key "$scheme$request_method$host$request_uri$args"; - Cloudflare 默认支持查询参数区分缓存,但如果开了「Cache Everything」规则,得确认没勾选「Ignore query string」
- 验证方法:抓包看响应头,如果
X-Cache: HIT且Age值很大,说明 CDN 没认出?v=的差异
最易被忽略的点:Service Worker 会劫持所有 CSS 请求并返回自己缓存的内容,哪怕你改了 URL、清了浏览器缓存,它照样发旧文件——上线新样式前,务必先 unregister 并清空它的 Cache Storage。


















