手摸手教你解決重定向緩存問題

手摸手教你解決重定向緩存問題css

問題產生:

測試粑粑:測試環境已經搭好了,前端打個包吧!
weber:好嘞!快速輸入命令:npm run build:stagging
三分鐘後……
測試粑粑:是否是打錯包了?怎麼還沒變?
weber:刷新下頁面試試!
測試粑粑:沒用鴨~
weber:蛤~清理下瀏覽器緩存!
測試粑粑:出來了,**牛皮鴨!!!html

問題到這裏,我陷入了沉思,咋回事呢,若是每次發佈須要用戶手動清除瀏覽器緩存,這無疑是一個巨大的bug?因而開始列出了問題排查清單:
一、刷新頁面從新進行了doc【index.html】請求,無效;而清理瀏覽器緩存缺生效了,說明瀏覽器緩存了文件致使刷新請求時仍是以前的文件。
二、webpack打包時,outputjscss加上了hash,那jscss應該就不會緩存。前端

開始排查

1、檢查了webpack打包配置:java

module.exports = {
  context : path.join(__dirname,'src'),
  entry:{
    main: './index.js',
    vender:['./jquery.js','./test.js']
  },
  module:{
    rules:[{
      test:/\.css$/,
      use: extractTextPlugin.extract({
        fallback:'style-loader',
        use:'css-loader'
      })
    }]
  },
  output:{
    path:path.join(__dirname, '/dist/js'),
    filename: 'bundle.[name].[hash].js',
  },
  plugins:[
    new extractTextPlugin('../css/bundle.[name].[hash].css')
  ]
}
複製代碼

發現webpack打包沒有問題。jquery

2、打包後的文件也沒有問題。

3、打包後生成的index.html文件引入。

3、查看network請求才恍然大悟:

index.html304請求,那說明index.html被緩存了。webpack

解決問題

開始尋找解決辦法,方法有不少,有前端配置的,也有後端配置的。ios

考慮到webpack打包生成的html只是做爲引入jscss的容器,若只是不緩存html文件,代價其實很小。選擇以下方法:nginx

一、在html head頭部添加不緩存html配置:web

注:metatml語言head區的一個輔助性標籤,其中的http-equiv字段定義了服務器和用戶代理的一些行爲。在以前的規範中,metahttp-equiv字段中有如下值與http header緩存相關的字段功能相似面試

<head>
  <meta http-equiv="pragma" content="no-cache">
  <meta http-equiv="cache-control" content="no-cache">
  <meta http-equiv="expires" content="0">
</head>
複製代碼

若採用這種方式,請在public文件加下的index.html配置。

二、修改nginx.conf,增長add_header Cache-Control 'no-cache, no-store, must-revalidate'不緩存html配置:

server {
  listen       80;
  server_name  localhost;

  root        /usr/share/nginx/html;
  index       index.html;

  location ~* \.(gif|jpg|jpeg|png|css|js|ico|eot|otf|fon|font|ttf|ttc|woff|woff2)$ {
      expires 1M;
      add_header Cache-Control "public";
  }

  location / {
      add_header Cache-Control 'no-cache, no-store, must-revalidate';
  }

  error_page  404              /index.html;
}
複製代碼

其實這兩個配置都是在請求head加上不緩存html的配置,一個在前端,一個在運維。翻閱w3c文檔發現,但如今w3c的規範字段中這些值已經被移除,一個很好的理由是:

Putting caching instructions into meta tags is not a good idea, because although browsers may read them, proxies won't. For that reason, they are invalid and you should send caching instructions as real HTTP headers.

綜合以後仍是第二種方案較爲完善。

bug再現:

weber:此次修改了nginx配置,此次打包應該不會出現上次的緩存問題了,不用手動清楚瀏覽器緩存了!
測試粑粑:牛皮鴨,我試試~
weber:(自信的小表情,期待的小紅手)~
測試粑粑:仍是有問題鴨!仍是沒更新過來!
weber:你是直接請求是吧?有沒有刷新頁面?
測試粑粑:沒有,直接請求的~
weber:好了,我知道了!

問題到這裏,又出現了bug。若是直接請求網址,是會請求到最新的html文件,可是還會存在用戶不刷新直接請求的狀況。

理清思路:

其實到這一步問題已經很清晰了,從新理一遍webpack打包過程、瀏覽器緩存策略,問題就很容易解決了。
1、webpack打包:

public/index.html:文件是一個會被 html-webpack-plugin 處理的模板。在構建過程當中,資源連接會被自動注入。另外,Vue CLI 也會自動注入 resource hint (preload/prefetch、manifest 和圖標連接 (當用到 PWA 插件時) 以及構建過程當中處理的 JavaScriptCSS 文件的資源連接。ouput裏面的文件都會inject

2、HTTP重定向:

服務器的nginx配置以下:

倘若輸入:https://example.comhttps://example.com/a都會定位到root下的index.html文件,也會觸發請求html文件。

3、瀏覽器緩存:

再次查看增長了不緩存html文件,請求狀態變成了200

所以,在不刷新瀏覽器的狀況下請求,html是沒有被請求的,仍然是第一次輸入網址請求回來的html文件,裏面的jscss也是以前的,因此瀏覽器不會再去請求jscss文件。解決辦法:

axios請求加上版本號,若是版本號對應不上,則返回code,讓前端去與用戶交互是否已經更新了,須要刷新頁面。

相關文章
相關標籤/搜索