一:現象
用戶端加載過H5頁面A,後來H5修改為A'釋出之後,在很長一段時間内,用戶端一直展示的是A,沒有更新為A'。
重新開機之後依然沒有更新,隻有清除緩存或者重裝APP才會更新。
二:分析
根據現象得出,是由于webview的緩存導緻頁面一直沒有更新。但是為什麼沒有更新?更新的機制是什麼?應該怎麼修改?
首先看下用戶端的緩存機制,CacheMode一共有五種
CacheMode {
// 如果頁面沒有強制任何特定行為(依賴服務端控制),如果本地有未過期的緩存,就會直接加載本地緩存,否則就請求網絡
LOAD_DEFAULT = -1
// 從API 11開始就廢棄了,和LOAD_DEFAULT行為一緻
LOAD_NORMAL = 0
// 隻要本地有緩存,不管有沒有過期,都使用本地緩存。否則就請求網絡
LOAD_CACHE_ELSE_NETWORK = 1
// 忽略本地緩存(就算有也不用),直接請求網絡
LOAD_NO_CACHE = 2
// 隻使用本地緩存,不請求網絡
LOAD_CACHE_ONLY = 3
}
重點看下LOAD_DEFAULT模式,這個是依賴服務端配置的緩存政策
http協定緩存機制
http協定緩存機制是指通過 HTTP 協定頭裡的 Cache-Control(或 Expires)和 Last-Modified(或 Etag)等字段來控制檔案緩存的機制。
Expires 是 HTTP1.0 标準中的字段,Cache-Control 是 HTTP1.1 标準中新加的字段,功能一樣,都是控制緩存的有效時間。當這兩個字段同時出現時,Cache-Control 是高優化級的。
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIiNDO3ATN3ETMjNGZvwFcvwVbvNmL1h2cuFWaq5yd3d3Lc9CX6MHc0RHaiojIsJye.jpg)
三:解決方案
用戶端:CacheMode使用LOAD_DEFAULT即可,依賴服務端控制緩存政策。為了解決線上版本緩存有效期時間過長的問題,可以在請求的url後面加無效參數,例如#,欺騙浏覽器url變動,強制浏覽器去伺服器更新一次。
服務端:修改nodejs express服務,設定靜态資源的時候設定了下這個Cache-Control屬性。修改方式可參考 Express 中設定緩存Cache-control的maxAge
伺服器配置:Nginx伺服器配置Cache-Control也是可行的。
緩存政策需要根據具體業務來确定,如果該頁面沒有要求實時更新,可以使用max-age=XX來控制,在再XX秒時間範圍内使用緩存,否則就請求網絡。
四:測試流程
使用max-age=60驗證頁面更新情況
前提,清除緩存,服務端先加上max-age屬性
用戶端先進入頁面緩存一次。
h5修改資源釋出
用戶端再60秒之内打開頁面,沒有更新,60秒之後再次打開,頁面正常更新。
五:注意事項
如果之前服務端沒有加任何控制緩存的參數(Cache-Control),用戶端緩存了該H5頁面,此時修改服務端緩存政策,用戶端在緩存過期之前是不會重新請求資源的。必須等到用戶端緩存過期,或者清除緩存才可以。
HTML頭部添加
并沒有生效,被忽略了
在服務端沒有配置任何緩存政策時,Android緩存有效期時間會很長,也就是長時間不會更新。而iOS每次進入頁面都會更新,由于iOS和Android核心不一樣,iOS是Safari,Android是chromium,處理方式可能會有差異。
在服務端沒有加任何控制緩存的參數情況下,使用pc端浏覽器打開H5,在H5修改之後,谷歌浏覽器也是沒有立即更新的,必須使用強制重新整理(Shift+F5),但是火狐浏覽器F5就可以正常重新整理了。谷歌浏覽器和Android内置浏覽器都是chromium核心,表現基本一緻。
檢視網頁響應頭
浏覽器打開該網頁,按F12,選擇Network,然後再重新整理下網頁,選擇左下欄第一個.html的頁面,右面的Headers裡面可以看到Cache-Control,說明服務端配置生效了。
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIiNDO3ATN3ETMjNGZvwFcvwVbvNmL1h2cuFWaq5yd3d3Lc9CX6MHc0RHaiojIsJye.jpg)
參考: