HTTP緩存
原因:
頻繁請求非常類費流量,且一直刷新使用者體驗相當不佳
緩存內容
主要是一些靜態資源(比如CSS,JS)
HTTP緩存頭部(後面會詳談)
Cache-Control
請求/響應頭,緩存控制
Expires
表資源過期時間,與max-age共存情況下優先級較低
Last-Modified
資源最新修改時間,由服務器響應給瀏覽器
if-Modified-Since
與Last-Modified一組,瀏覽器請求服務器協帶,服務器會比對這個確認版本是否更新
Etag
資源標籤,服務器響應給瀏覽器
if-None-Match
與Etag一組,瀏覽器請求服務器協帶,服務器會比對這個確認版本是否更新
HTTP 緩存工作方式
現在開始假設服務器在跟瀏覽器對話
情境一 服務器與瀏覽器約定一個文件過期時間(Expires)
瀏覽器:
1
ㄟㄟ,服務器,你的文件找一下有沒有一個叫做main.js的文件,找到後再給我
服務器:
1
OKOK,可是我怕你跟一直跟我要,所以給你一個Expires,等過了這個時間你再跟我要吧!
總結
Expires(透過響應頭)主要是約定一個過期時間,在過期時間前客戶端不會向服務器要資源
延伸情況二
上面情況,假如文件過期後,該文件在服務器端沒有更新,就代表客戶端請求道的文件不就一模一樣,因此出了情境二
情境二 在Expires基礎上再加上Last-Modified以及if-Modified-Since
瀏覽器:
1
ㄟㄟ,服務器,你的文件找一下有沒有一個叫做main.js的文件,找到後再給我
服務器:
1
OKOK,可是我怕你跟一直跟我要,所以給你一個Expires,等過了這個時間你再跟我要吧! 啊還有我怕到時候文件沒更新你又要我找給你,所以我回傳一個Last-Modified喔
瀏覽器:
1
好,那等文件過期後我再回傳if-Modified-Since給你喔,方便你核對版本
總結:
if-Modified-Since與Last-Modified回傳樣子是
- 如果Expires還沒過期,則瀏覽器聰明的使用緩存
- 過期了之後,瀏覽器請求時附上if-Modified-Since, 假如文件在服務器端有更新,服務器回傳304 Not Modified
延伸情況三
情況二可以發現,if-Modified-Since與Last-Modified這兩個最小單位是秒,如果今天更新的時間與那兩個相差不到1秒文件就不會更新。假如今天我服務器的平台過大,比方說FB,總是會有這個情況發生
情況三 在情況二的基礎上,增加一個文件內容唯一標示Etag與if-None-Match, 然後在加入max-age
- max-age優先度比Expires高,因此這裡expires會被取代,單位是秒,表幾秒後緩存過期
- Etag與if-None_Match的關係就像是Last-Modified以及if-Modified-Since
- 所以在這個情況Expires與Last-Modified其實沒啥用
瀏覽器:
1
ㄟㄟ,服務器,你的文件找一下有沒有一個叫做main.js的文件,找到後再給我
服務器:
1
OKOK,可是我怕你跟一直跟我要,所以給你一個Expires,等過了這個時間你再跟我要吧! 啊還有我怕到時候文件沒更新你又要我找給你,所以我回傳一個Last-Modified喔,但好像不夠精準,算了我再傳一個Etag以及max-age給你好了
瀏覽器:
1
好,既然有更精準的Etag以及max-age那我當然看這個囉,那我之後再回傳if-None-Match給你做核對版本
總結:
到這裡瀏覽器已經可以精準確定緩存時間以及緩存文件是否相同
CDN緩存
CDN自己也有緩存,並將緩存的靜態資源傳給瀏覽器,跟瀏覽器的行為也很像
瀏覽器:
1
ㄟㄟ,服務器,你的文件找一下有沒有一個叫做main.js的文件,找到後再給我
服務器:
1
別找我,找我老弟CDN吧