站長阿川

站長阿川私房教材:
學 JavaScript 前端,帶作品集去面試!

站長精心設計,帶你實作 63 個小專案,得到作品集!

立即開始免費試讀!

前端發版總被用戶說「沒更新」?一文搞懂瀏覽器快取,徹底解決!

image

有時候我們發了新版,結果用戶看到的還是舊介面。
你:「我更新了啊!」
用戶:「我這兒沒變啊!」
然後你倆開始互相懷疑人生。
那怎麼辦?總不能讓用戶都清快取吧?
當然不能。
我們得讓瀏覽器自己知道「該換新的了」。
核心思路就一條:讓靜態資源的檔名變一變。
瀏覽器靠檔名判斷是不是同一個檔案。
檔名變了,它就會重新下載。

方法1:加時間戳(簡單粗暴)

以前:

<script src="/js/app.js"></script>

現在:

<script src="/js/app.js?v=20250901"></script>

或者用時間戳:

<script src="/js/app.js?t=1725153600"></script>

發版的時候,改一下vt的值,瀏覽器看到後發現檔名不一樣,就會重新下載。

優點:簡單,立馬見效
缺點:每次發版都得手動改,容易忘記。

方法2:用建置工具加hash(推薦!)

這是現在最主流的做法。
你用WebpackViteRollup這些工具打包時,它會自動給檔名加一串hash

<script src="/js/app.a1b2c3d.js"></script>

你代碼一改,hash就變。
比如下次變成:

<script src="/js/app.e4f5g6h.js"></script>

瀏覽器看到後發現檔名不一樣,會自動拉新檔。
使用時需要檢查你的打包配置,確保輸出檔案帶hash。

Vite配置(vite.config.js):

export default defineConfig({
  build: {
    rollupOptions: {
      output: {
        entryFileNames: 'assets/[name].[hash].js',
        chunkFileNames: 'assets/[name].[hash].js',
        assetFileNames: 'assets/[name].[hash].[ext]'
      }
    }
  }
})

Vue CLI(vue.config.js):

module.exports = {
  filenameHashing: true, // 預設就是 true,別關掉!
}

只要這個開著,JS/CSS 檔名就會變,瀏覽器就會更新。

優點:全自動,不用操心
優點:用戶無感知,體驗好
優點:還能利用快取(沒改的檔案hash不變,繼續用舊的)

來看看Vue的專案

只要你用的是Vue CLI、Vite或 Webpack打包,發版時預設就解決了快取問題。
因為它們會自動給檔名加hash
比如你打包後:

dist/
├── assets/app.8a2b1f3.js
├── assets/chunk-vendors.a1b2c3d.js
└── index.html

你改了代碼,再打包,hash就變了:

assets/app.x9y8z7w.js  # 新檔

雖說是這樣,但為啥還有人卡在舊版本?

檔名帶hash,但index.html這個入口檔本身可能被快取了

流程:

  • index.html裡引用了app.8a2b1f3.js
  • 用戶第一次訪問,加載了index.html和對應的JS
  • 你發新版,index.html指向app.x9y8z7w.js
  • 但用戶瀏覽器快取了舊的index.html,還在引用app.8a2b1f3.js
  • 結果:頁面還是舊的

這是入口檔快取導致的發版無效。

解決方案

方法1:讓index.html不被快取

這是最簡單有效的辦法。
配置Nginx,讓index.html不快取:

location = /index.html {
    add_header Cache-Control "no-cache, no-store, must-revalidate";
    add_header Pragma "no-cache";
    add_header Expires "0";
}

這樣每次用戶訪問,都会重新下載最新的 index.html,自然就拿到新的 JS 檔名。

注意:其他靜態資源(js/css)可以長期快取,只有 index.html 要禁快取。

方法2:根據版本號來控制

每一次更新都新建一個資料夾

image

然後修改Nginx配置:

location / {
    root /home/server/html/yudao-vue3/version_1_2_5;
    index index.html index.htm;
    try_files $uri $uri/ /index.html;
}

最後
快取這事看著小,真出問題能讓我們忙半天。
提前設好機制,發版才能睡得香。
搞定!

我是大華,專注分享前後端開發的實戰筆記。關注我,少走彎路,一起進步!

📌往期精彩

《Elasticsearch 太重?來看看這個輕量級的替代品 Manticore Search》
《只會寫 Mapper 就敢說會 MyBatis?面試官:原理都沒懂》
《別學23種了!Java專案中最常用的6個設計模式,附案例》
《寫給小公司前端的 UI 規範:別讓頁面醜得自己都看不下去》
《Vue3+TS設計模式:5個真實場景讓你代碼更優雅》


原文出處:https://juejin.cn/post/7545252678936100918


共有 0 則留言


精選技術文章翻譯,幫助開發者持續吸收新知。
站長阿川

站長阿川私房教材:
學 JavaScript 前端,帶作品集去面試!

站長精心設計,帶你實作 63 個小專案,得到作品集!

立即開始免費試讀!