頁面改了、样式表換了,訪客打開却還是舊样子;图片明明替換過,前台顯示的仍是上一版。這類問题很少是代碼寫错了,多半是缓存和资源版本没安排好。缓存本来是為了让站点更快,設定得不合适,就變成“改了没人看到”。下面這份自查围绕缓存头、资源命名和更新後的清理動作展開,适合每次前端资源上线後過一遍。
先分清站点上有几层缓存
排查之前,最好把鏈路上可能缓存的地方列出来,否則很容易只清了一层,另一层還在發舊文件。
- 浏览器缓存:訪客本地儲存的副本,由响應头里的 Cache-Control、Expires、ETag 等字段决定存多久。
- CDN 或反向代理缓存:位于服務器前面的节点,通常按 URL 缓存整份响應,需要主動清理或等它自然過期。
- 服務端缓存:頁面片段缓存、對象缓存、模板编译缓存等,属于應用层面的机制。
- 本地開發缓存:自己电脑上的浏览器缓存,調试时最容易誤判,先確認是不是只影响你一個人。
一個简單的判断方法:無痕窗口打開是否正常、換一台设备是否正常、带随机參數訪問是否正常。三種结果组合起来,基本能定位問题在哪一层。
缓存头怎么寫才不容易出错
核心思路是按文件類型区分,而不是给整站套一個统一的时長。
静態资源适合長缓存
CSS、JS、字体、图标這類内容不常變,且變了一定會改文件名的资源,可以設定較長的 max-age,並配合 immutable,让浏览器在有效期内直接使用本地副本,不再發請求確認。
HTML 與接口資料适合短缓存
頁面文档本身承载着最新的内容结构,如果给它设了很長的缓存,更新就传導不出去。通常做法是短缓存加协商缓存,让浏览器带着 ETag 或 Last-Modified 询問一次,服務端返回 304 即可,既省流量又不至于發舊内容。
別把不该缓存的地址缓存住
登入態頁面、购物车、後台入口、带用戶身份的接口,都應该明确标记為私有或不缓存,避免在共享节点上被其他訪客讀到。
给资源加版本标识
让浏览器“知道文件變了”,靠的是地址變化,而不是反复清缓存。常见的几種做法:
- 文件名哈希:app.8f3c1a.css 這類命名,内容一變文件名就變,最稳妥,也方便 CDN 分层缓存。
- 查询參數:app.css?v=20240612,改動成本低,但部分缓存节点對查询串的處理不一致,需要確認 CDN 的缓存键是否包含參數。
- 目錄版本:把整批资源放進带版本号的目錄,适合整体發布,但要注意舊目錄的清理,別让磁盘一直堆着歷史文件。
無论用哪種方式,都要保證 HTML 中引用的地址和實际發布的文件名一致,改完顺手全局搜一遍舊地址有没有残留。
更新之後怎么让舊缓存失效
- 確認新文件已经部署到所有节点,而不是只传了一台机器。
- 如果资源換了文件名,HTML 引用已经指向新地址,通常不需要額外操作。
- 如果沿用舊地址,就需要在 CDN 控制台提交刷新,或等待缓存自然過期。
- 服務端缓存按业務逻辑清理,模式缓存、頁面缓存、對象缓存分头確認。
- 用無痕窗口和外部網絡各訪問一次,核對返回的响應头是否符合预期。
缓存的目标不是让内容一直不變,而是让不變的東西安心缓存,让會變的東西及时更新。
一份可以照着走的自查清單
- 静態资源是否都带版本标识,且版本随内容變化。
- HTML 文档的缓存时長是否足够短,不會挡住内容更新。
- 登入態與個性化頁面是否已明确禁止公共缓存。
- CDN 的缓存键設定是否和實际需求一致,有没有漏掉關键參數。
- 每次發布是否有固定的刷新步骤,而不是出了問题再手動清。
- 缓存相關的問题是否记錄到运维文档里,方便下次快速定位。
把這几項固定成發布流程的一部分,改版和日常更新都會省心不少:訪客拿到的是新版,服務器也不必為同一份文件反复應答。