最近寫了一個面向大眾的導航站,初期一直在修改js和css,由於是託管到coding上的,瀏覽器的快取問題是真的要命,自己倒是知道清理快取,但其他人不知道啊,所以在網上查了下解決辦法,特來總結一下

前言

瀏覽器的快取機制其實是一個很好的最佳化機制,可以避免重複請求相同的資源,減輕伺服器的壓力,也可以加快使用者的二次讀取。但凡事都有優缺點,快取的存在會導致css,js或者其他靜態資源不能及時更新。有時修改了html,html一般不會讀取快取,但css和js讀取了快取,就會出現一些莫名其妙的問題,而到了使用者那邊,則會一臉懵逼。

瀏覽器的快取原理

這個我也不太懂,就知道分為強制快取和協商快取。當二次開啟網頁時,瀏覽器會先對快取發起http請求,只要請求的資源存在快取並且該資源的請求頭

expires

cache-control

中存在快取的標誌,那就預設讀取快取,如果快取失效但快取依然存在,這時有會對伺服器發出http請求,透過

last-modified

etag

兩個請求頭驗證是否存在協商快取,存在協商快取就讓瀏覽器照樣讀取快取。

當然,如果你資源已經不存在了或者明確禁止快取,那瀏覽器也不可能使用快取,這也是解決快取問題的辦法

如何解決靜態資源的快取問題

強制快取

強制快取兩個請求頭,

expires

cache-control

expires

不怎麼用,是http1。0提出的一個表示資源過期時間的header 而

cache-control

出現於 HTTP / 1。1,優先順序高於 Expires,同樣也可以表示資源過期時間 當然

cache-control

並沒有這麼簡單,有很多值,但常用的基本就是下面5個值 - public:所有內容都將被快取(客戶端和

代理伺服器

都可快取) - private:所有內容只有客戶端可以快取,Cache-Control的預設取值 - no-cache:客戶端快取內容,但是是否使用快取則需要經過協商快取來驗證決定 - no-store:所有內容都不會被快取,即不使用強制快取,也不使用協商快取 - max-age=xxx (xxx is numeric):快取內容將在xxx秒後失效

如何解決靜態資源的快取問題

強制快取是否生效,可以檢視控制檯的network選項,下面的size屬性,一般就是

from memory cache

或者

from disk cache

,一個是從記憶體中載入快取,一個是硬碟中載入快取,區別就是記憶體要快些,一般先是讀取硬碟中的快取,要是你重新整理一下,就從記憶體中讀取,不然重新整理的時候怎麼那麼快

如何解決靜態資源的快取問題

協商快取

當強制快取失敗,瀏覽器就請求伺服器,如果伺服器覺得用快取沒問題,資源又沒有更新,那麼,即使快取設了到期時間,瀏覽器依然會讀取,此時伺服器返回304,如果資源更新了,就從伺服器請求更新,返回200。如何判斷資源是否更新,就是靠

last-modified

etag

兩個請求頭,這裡我就不多講了

但是要注意,強制快取要優先於協商快取,所以嘛,就算你更新了,瀏覽器依舊會讀取快取

,這也就是問題的由來,解決辦法很簡單,要麼直接禁用快取,告訴瀏覽器不準使用我的快取,每次都從伺服器載入。要麼就是把檔名字改了,快取名字對不上也就不會讀取快取了

解決辦法

知乎上有個回答說的挺好

瀏覽器是好人(meta),瀏覽器有點壞(版本號),瀏覽器老子看你不爽了,我要“欺騙你”(md5)

meta快取頭設定為禁止快取

在html的head標籤中加入下面內容,就可以禁止瀏覽器讀取快取

<

meta

http-equiv

=

“Cache-Control”

content

=

“no-cache, no-store, must-revalidate”

/>

<

meta

http-equiv

=

“Pragma”

content

=

“no-cache”

/>

<

meta

http-equiv

=

“Expires”

content

=

“0”

/>

Cache-Control

作用於

HTTP1。1

Pragma

作用於

HTTP1。0

Expires

作用於

proxies

但這樣瀏覽器在資源沒修改的時候也不能載入快取,十分影響體驗

js、css加上版本號

當請求js、css的時候,給他們最後加上版本號,瀏覽器發現版本高了,就自然而然不會讀取低版本的快取了 版本號並不需要改變檔名,只需要在呼叫js、css的時候在最末尾加上

?v=1。0

即可,比如

custom。css

?v=1。0

main。js?v=2。0

當然版本號也可以自動新增

隨機數

,不過這樣就違背了版本號的初衷了,這樣同樣瀏覽器在資源沒修改的時候也不能載入快取,影響體驗 隨機版本號的新增方法,使用一個隨機函式即可,當然,這樣就只能透過js中寫js的呼叫語句,比如

document

write