如何强制清除缓存需要打通三层缓存浏览器 → CDN → 源站。根据已缓存还是即将发布策略完全不同一、三层缓存架构用户浏览器本地磁盘/内存缓存 ↓ CDN 边缘节点分布式缓存 ↓ OSS/源站对象存储清除难度浏览器缓存 CDN 缓存 OSS 缓存二、已上线场景的紧急清除方案用户已缓存旧版本方案 1URL fingerprinting最彻底100% 生效原理改变文件 URL浏览器视为全新资源。操作# 原文件app.a1b2c3.js已被缓存# 紧急修复后修改构建配置强制更换 hash# webpack/vite 配置在文件内容 hash 基础上增加构建时间戳# vite.config.tsexportdefault{build:{rollupOptions:{output:{entryFileNames:assets/[name]-${Date.now()}.js, // 强制新文件名 chunkFileNames:assets/[name]-${Date.now()}.js,}}}}Jenkins 配合stage(Emergency Cache Bust){steps{// 紧急版本在文件hash后加时间戳参数sh # 重命名所有 JS/CSS 文件追加 ?_v${BUILD_NUMBER}# 然后同步修改 HTML 中的引用路径 sed -i s/\\.js/.js?_v${BUILD_NUMBER}/g dist/index.html }}方案 2HTML 入口强制无缓存 动态加载带版本号确保index.html不被缓存且内部引用带版本号!-- index.html 必须配置Cache-Control: no-cache --scriptsrcapp.js?v20240130-001/scriptlinkrelstylesheethrefstyle.css?v20240130-001自动化方案构建时注入// vite/webpack 插件在文件名后追加 query stringconstversionprocess.env.BUILD_NUMBER||Date.now();// 输出app.js?_1706600000方案 3CDN 强制刷新清除边缘节点缓存即使文件名没变强制 CDN 回源拉取最新内容阿里云 CLI# 刷新全站慎用有额度限制aliyun cdn RefreshObjectCaches--ObjectPathhttps://your-domain.com/*--ObjectTypeDirectory# 刷新特定文件aliyun cdn RefreshObjectCaches--ObjectPathhttps://your-domain.com/app.js--ObjectTypeFile腾讯云coscli debug-rhttps://your-cdn.com/-tflush注意CDN 刷新不会清除用户浏览器缓存只是保证 CDN 节点是最新版。三、浏览器层强制清除针对已缓存的用户方法 1Service Worker 清理PWA 应用如果项目注册了 SW可以编写自杀式清理逻辑// 在 app.js 最顶部注入紧急版本if(serviceWorkerinnavigator){navigator.serviceWorker.getRegistrations().then(registrations{for(letregistrationofregistrations){registration.unregister();// 注销所有 SW}});// 清理所有缓存caches.keys().then(cacheNames{cacheNames.forEach(cacheName{caches.delete(cacheName);});});}方法 2HTML Meta 标签较弱仅对部分浏览器有效metahttp-equivCache-Controlcontentno-cache, no-store, must-revalidatemetahttp-equivPragmacontentno-cachemetahttp-equivExpirescontent0缺点仅对当前页面有效对外部引用的 JS/CSS 无效。方法 3HTTP Header 强制重新验证紧急情况下临时修改 OSS 配置# 将已有缓存的文件改为必须重新验证ossutil set-meta oss://bucket/app.js Cache-Control:no-cache--update四、用户端操作不得已的兜底方案当技术层面无法立即生效指导用户操作操作WindowsMac强制刷新绕过缓存Ctrl F5或Ctrl Shift RCmd Shift R清空缓存Ctrl Shift Delete→ 选缓存Cmd Shift Delete无痕模式Ctrl Shift NCmd Shift N前端提示代码检测到可能是旧版本时弹出// 在 app.js 中加入版本检测逻辑constCURRENT_VERSION1.2.3;// 每次发版更新fetch(/version.txt?_Date.now())// 带时间戳防止缓存.then(rr.text()).then(serverVersion{if(serverVersion.trim()!CURRENT_VERSION){alert(检测到新版本请按 CtrlF5 强制刷新);// 或自动刷新location.reload(true);}});五、预防性最佳实践避免未来需要强制清除1. 文件名指纹化Hash 策略// 构建输出示例dist/assets/app.a1b2c3d.js # content-hash文件内容变hash 才变 style.e4f5g6h.css # 永久缓存immutable index.html # 永不缓存2. HTML 禁用缓存入口保鲜# Nginx 配置示例 location ~* \.html$ { add_header Cache-Control no-cache, no-store, must-revalidate; add_header Pragma no-cache; expires 0; }3. OSS 上传策略版本化目录# 不按版本覆盖而是新建目录oss://bucket/project/v168/# 旧版本保留oss://bucket/project/v169/# 新版本oss://bucket/project/current/# 软链接到最新版或反向代理回滚时只需切换current指向v168URL 不变但内容回退需配合 CDN 刷新。4. 构建时自动添加 Query String// Jenkins Pipeline自动给所有资源加时间戳sh find dist -name *.js -o -name *.css | while read file; do filename$(basename $file) # 在 index.html 中替换引用 sed -i s|$filename|$filename?_${BUILD_NUMBER}|g dist/index.html done 六、面试标准回答问部署后用户还是看到旧版本如何强制清除缓存我会分三层处理CDN 层立即调用 CDN 刷新 API清除边缘节点缓存但无法触及浏览器浏览器层通过改变 URL文件名加 hash 或 query string让浏览器识别为新资源这是唯一 100% 生效的方案预防层确保 HTML 永不缓存no-cacheJS/CSS 使用 content-hash 命名实现长期缓存且自动失效。如果紧急线上故障需要立即生效我会临时在文件名后追加?_t${timestamp}并重新部署虽然牺牲缓存性能但能确保用户立即获取最新代码。七、快速决策流程图发现用户缓存旧版本 ↓ 是否需要立即生效 ↓ 是 → 修改构建配置添加 query string如 ?v2→ 重新部署 ↓ 否 → 仅刷新 CDN 缓存 → 等待浏览器缓存自然过期或指导用户 CtrlF5终极建议不要试图清除缓存而是让缓存失效——通过改变 URLhash 或版本号是最可靠的手段。