緩存的目的
通常而言兔沃,用戶訪問一個web頁面的頻率遠(yuǎn)高于web頁面更新的頻率,因此多數(shù)時候用戶從服務(wù)器獲取的html、js颖变、css以及圖片等內(nèi)容都是相同的。如果每次訪問都從服務(wù)器獲取這些靜態(tài)內(nèi)容即降低了頁面加載的速度听想,又占用了多余的服務(wù)器帶寬腥刹,顯然是一件很不劃算的事,所以http協(xié)議設(shè)計了一套規(guī)范汉买,通過若干個http header的結(jié)合形成了一個完整的工作體系衔峰。
緩存的三要素
http協(xié)議中存在若干與緩存有關(guān)的header,從功能上來說录别,大約可以分為三類:
- 緩存存儲策略
- 緩存過期策略
- 緩存對比策略
1. 緩存存儲策略
緩存存儲策略決定了客戶端是否應(yīng)該存儲http的response朽色。與緩存存儲有關(guān)的http header主要為response header中的 Cache-Control
。該header有下面幾個對應(yīng)的值: Public
组题、Private
葫男、no-cache
、max-age
崔列、no-store
梢褐。除了no-store,其它幾種都會表明response應(yīng)該被客戶端緩存赵讯。每種指令的詳細(xì)說明見下表:
指令 | 說明 |
---|---|
Public | 所有內(nèi)容都將被緩存(客戶端和代理服務(wù)器都可緩存) |
private | 內(nèi)容只緩存到私有緩存中(僅客戶端可以緩存盈咳,代理服務(wù)器不可緩存) |
max-age=xxx (xxx is numeric) | 緩存的內(nèi)容將在 xxx 秒后失效,失效前可以直接使用本地緩存边翼,失效后必須向服務(wù)器確認(rèn)資源是否已經(jīng)改變鱼响。 |
no-store | 完全不在客戶端緩存 |
no-cache | 可以認(rèn)為等同于max-age=0的情況,即將response緩存在客戶端组底,但是之后每次都向服務(wù)器確認(rèn)資源是否已經(jīng)改變 |
2. 緩存過期策略
緩存過期策略決定了客戶端存儲在本地的緩存數(shù)據(jù)是否已過期丈积,如未過期則可以直接使用本地存儲的數(shù)據(jù),否則就需要發(fā)請求到服務(wù)端嘗試重新獲取數(shù)據(jù)债鸡。
與緩存過期策略有關(guān)的http header為Expires
江滨。Expires
表示緩存數(shù)據(jù)有效的絕對時間,告訴客戶端到了這個時間點(diǎn)后本地緩存就失效了厌均,在這個時間內(nèi)客戶端可以不請求服務(wù)器而直接從本地緩存中使用已存儲的結(jié)果唬滑。
不過這里就不得不吐槽一下http的設(shè)計了,明明可以更加清晰一些,卻非要在不同的頭部之間弄出功能重合的部分:除了Expires
以外晶密,還有若干方法可以指定response的過期時間擒悬,如上面我們提到過的Cache-Control
中的max-age
和no-cache
。max-age=xxx
其實(shí)相當(dāng)于Expires : date(當(dāng)前時間戳+xxx)
(date(當(dāng)前時間戳+xxx)表示將當(dāng)前時間戳+xxx的值轉(zhuǎn)化為日期格式)而Cache-Control:no-cache
和 Cache-Control:max-age=0
(單位是秒)相當(dāng)惹挟。
需要注意的是:no-cache
和max-age=xxx
的優(yōu)先級高于 Expires
茄螃,當(dāng)它們同時存在的時候缝驳,后者會被覆蓋掉连锯。其次, 緩存數(shù)據(jù)過期只是告訴客戶端不能再直接從本地讀取緩存了用狱,而是需要再發(fā)一次請求到服務(wù)器去確認(rèn)运怖。具體什么情況下本地存儲的數(shù)據(jù)還可以繼續(xù)使用就與緩存對比策略有關(guān)了。
3. 緩存對比策略
客戶端檢測到數(shù)據(jù)過期后夏伊,如果服務(wù)器在首次響應(yīng)時返回了Last-Modified
摇展、ETags
,則客戶端會發(fā)起一個帶標(biāo)識If-Modified-Since
溺忧、If-None-Match
的http請求到服務(wù)器咏连,如果服務(wù)器根據(jù)這兩個標(biāo)識判斷響應(yīng)仍然有效,則返回304告訴客戶端取本地緩存數(shù)據(jù)來用即可鲁森。
一點(diǎn)要注意的問題
如果服務(wù)端返回的響應(yīng)中沒有指明max-age
祟滴、no-cache
或Expires
時,客戶端是否會緩存http response呢歌溉?通過Charles等抓包工具可以發(fā)現(xiàn)垄懂,客戶端一樣會進(jìn)行緩存。那么緩存的過期時間怎么得到呢痛垛?
當(dāng)http響應(yīng)中沒有指明過期時間時草慧,瀏覽器會取響應(yīng)頭中的Date 與 Last-Modified 之間的差值的10%作為緩存有效時間。
總結(jié)
http緩存機(jī)制實(shí)際上是我們上面提到的三種策略相互綜合的結(jié)果匙头,所以遇到和http緩存相關(guān)的問題時漫谷,首先需要從http報文找到三種策略相關(guān)的值,才能進(jìn)一步分析出問題出現(xiàn)的原因所在蹂析。
以上舔示。