根本原因是浏览器缓存了的响应,URL不变则复用旧资源;解决方法包括:加版本参数(如?v=hash)、用构建工具注入内容哈希、服务端配置Cache-Control。
根本原因是浏览器缓存了 的响应,即使你改了文件内容,URL 没变,它就直接从磁盘读旧资源。这不是 bug,是 HTTP 缓存的正常行为——但开发时很烦人。
最常用、最可控的方式是在 的 href 末尾加查询参数,比如 ?v=1.0.1 或 ?t=1715823495。服务器不会处理这个参数,但浏览器会把它当作全新 URL,从而绕过缓存。
实际操作注意这几点:
main.css?v=hash;?t=Date.now(),但上线前必须去掉,否则无法利用长期缓存;?v=1.0 这类静态版本号——改多次只生效一次,因为浏览器仍可能缓存该 URL。时间戳在本地开发时看似方便,但存在两个问题:一是每次保存都生成新 URL,浏览器无法复用已有缓存;二是多人协作时,不同机器生成的时间戳不同,CDN 或代理可能缓存多个副本。
真正健壮的做法是基于文件内容生成哈希,比如 Webpack 的 [contenthash],Vite 的 __vite__css 插件默认支持。这样只要 CSS 内容不变,URL

前端加参数是“绕开”缓存,而服务端控制才是“管住”缓存。如果你能改 Nginx / Apache / Vercel / Netlify 的配置,优先设置 CSS 文件的 Cache-Control 响应头:
no-cache 或 max-age=0;public, max-age=31536000(1 年),并确保文件名含哈希(即“内容寻址”);immutable 除非你确认永不变更——它会让某些浏览器忽略后续的 ETag 校验。只靠前端加参数,缓存逻辑就散落在 HTML、构建配置、甚至开发者脑中;统一由服务端定义,才不容易出错。