web緩存的工作原理
所有的緩存都是基于一套規(guī)則來確定什么時(shí)候使用緩存的副本提供服務(wù)。這些規(guī)則有的可以通過協(xié)議定義(比如HTTP1.0和HTTP1.1),有的也可以通過緩存的管理員設(shè)置(如DBA、代理服務(wù)器管理員或者開發(fā)者等)。
瀏覽器端的緩存機(jī)制
簡單來說,就是把副本保存在了本地,不需要每次都向服務(wù)器端請求。但是每次讀取緩存就會(huì)有問題,假如服務(wù)器端的內(nèi)容更新了呢?因此,服務(wù)器端會(huì)和客戶端約定一個(gè)有效期,在有效期內(nèi)的可以直接讀緩存。
但是,假如有效期過了,但是服務(wù)器端的內(nèi)容依然沒有改變呢,其實(shí)這個(gè)時(shí)候還是可以讀緩存的,只是需要通過判斷得知服務(wù)器端內(nèi)容是否改變。
大抵就是這兩個(gè)需要考慮的問題:
- 如何判斷有效期(新鮮度,過期機(jī)制)
- 如果超出有效期,服務(wù)器端內(nèi)容是否改變 (校驗(yàn)值,驗(yàn)證機(jī)制)
瀏覽器緩存的控制
- 使用HTML標(biāo)簽
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
上述代碼的作用是告訴瀏覽器當(dāng)前頁面不被緩存,每次訪問都需要去服務(wù)器拉取。使用上很簡單,但只有部分瀏覽器可以支持,而且所有緩存代理服務(wù)器都不支持,因?yàn)榇聿唤馕鯤TML內(nèi)容本身。
- 使用HTTP協(xié)議頭
Cache-control VS Expires
作用一致,都指有效期,不過cache-control選擇更多更細(xì)致,優(yōu)先級(jí)也更高。
Last-Modified/ETag
如果緩存內(nèi)容超出有效期,則需要去服務(wù)器端驗(yàn)證是否是最新的,此時(shí)則通過Last-Modified/ETag值來驗(yàn)證。
Last-Modified/If-Modified-Since
這是驗(yàn)證服務(wù)器端文件是否更新的第一種方式。
如圖所示,在第一次請求時(shí),響應(yīng)頭會(huì)將Last-Modified信息返回。

在按下ctrl+r強(qiáng)制刷新時(shí),請求會(huì)跳過max-age和Expires向服務(wù)器端發(fā)送請求,并在Request Headers中加入If-Modified-Since值,該值就是上一次請求中的Last-Modified值。

ETag/If-None-Match
這是驗(yàn)證服務(wù)器端是否更新的第二種方式。
實(shí)際上ETag并不是文件的版本號(hào),而是一串可以代表該文件唯一的字符串(Apache中,ETag的值,默認(rèn)是對文件的索引節(jié)(INode),大小(Size)和最后修改時(shí)間(MTime)進(jìn)行Hash后得到的。)
當(dāng)客戶端發(fā)現(xiàn)和服務(wù)器約定的直接讀取緩存的時(shí)間過了,就在請求中發(fā)送If-None-Match選項(xiàng),值即為上次請求后響應(yīng)頭的ETag值,該值在服務(wù)端和服務(wù)端代表該文件唯一的字符串對比(如果服務(wù)端該文件改變了,該值就會(huì)變),如果相同,則相應(yīng)HTTP304,客戶端直接讀取緩存,如果不相同,HTTP200,下載正確的數(shù)據(jù),更新ETag值。
如果Request Headers中既有If-None-Match又有If-Modified-Since,則忽略If-Modified-Since。因?yàn)镋Tag解決了Last-Modified的幾個(gè)問題:
- Last-Modified只能精確到秒級(jí)別
- 有時(shí)候文件的時(shí)間雖然變了,但是內(nèi)容卻沒有改變
小結(jié)

轉(zhuǎn)自 http://web.jobbole.com/82997/