http緩存分為強緩存和協(xié)商緩存。

● 每次發(fā)起請求,瀏覽器都會先在瀏覽器緩存中查找該請求的結(jié)果以及緩存標(biāo)識。
● 每次拿到請求結(jié)果都會將結(jié)果和緩存標(biāo)識存入瀏覽器緩存中。
強緩存
強緩存就是強制緩存,不需要發(fā)送請求到服務(wù)端,直接讀取瀏覽器本地緩存。
在 Chrome 的 Network 中顯示的 HTTP 狀態(tài)碼是 200 ,在 Chrome 中,強制緩存又分為 disk cache (存放在硬盤中)和 memory cache (存放在內(nèi)存中),存放的位置是由瀏覽器控制的。
● 內(nèi)存緩存(from memory cache):js和圖片等文件解析執(zhí)行后直接存入內(nèi)存緩存中,那么當(dāng)刷新頁面時只需直接從內(nèi)存緩存中讀取。
● 硬盤緩存(from disk cache):硬盤緩存則是直接將緩存寫入硬盤文件中,讀取緩存需要對該緩存存放的硬盤文件進(jìn)行I/O操作,然后重新解析該緩存內(nèi)容,讀取復(fù)雜,速度比內(nèi)存緩存慢。
Cache-Control
HTTP/1.1 中新增的屬性,在請求頭和響應(yīng)頭中都可以使用。
常見屬性值如有:
- max-age:用來設(shè)置資源可以緩存多長時間,單位s;
- public:指示響應(yīng)可被任何緩存區(qū)緩存;
- private:只能針對個人用戶,而不能被代理服務(wù)器緩存;
- no-cache:不使用強緩存,需要與服務(wù)器驗證,評估緩存響應(yīng)的有效性;
- no-store:禁止一切緩存(這個才是響應(yīng)不被緩存的意思);
cache-control: public, max-age=3600
如上響應(yīng)頭,表示則該資源會被緩存(3600秒) 1 小時,在 1 小時內(nèi)都會從緩存中獲取資源直接使用。
Expires
響應(yīng)頭包含日期/時間(GMT時間), 即在此時間之后,響應(yīng)過期。
expires: Wed, 21 Oct 2015 07:28:00 GMT
無效的日期,比如 0, 代表著過去的日期,即該資源已經(jīng)過期。
注意:Expires響應(yīng)頭是一個絕對時間,而Cache-Control是相對時間。
協(xié)商緩存
協(xié)商緩存就是強緩存失效后,瀏覽器攜帶緩存標(biāo)識向服務(wù)器發(fā)起請求,由服務(wù)器根據(jù)緩存標(biāo)識決定是否使用緩存的過程,主要有以下兩種情況:
● 協(xié)商緩存生效,返回304 not modified,告知瀏覽器緩存可用。
● 協(xié)商緩存失效,返回200和數(shù)據(jù)(可能會更新強緩存,具體看服務(wù)器操作)。
控制協(xié)商緩存的字段分別有:Last-Modified / If-Modified-Since和 Etag/ If-None-Match。其中Etag / If-None-Match的優(yōu)先級比Last-Modified /If-Modified-Since高。
注意:服務(wù)端返回的響應(yīng)頭中得包含Last-Modified或者Etag這兩個響應(yīng)頭之一,下次瀏覽器請求該資源才會帶上對應(yīng)的請求頭。
Last-Modified
Last-Modified是服務(wù)器響應(yīng)請求時,返回該資源文件在服務(wù)器最后被修改的時間。
第二次發(fā)起請求的時候,請求頭會帶上上一次響應(yīng)頭中的 Last-Modified的時間,并放到If-Modified-Since 請求頭中。服務(wù)端根據(jù)文件最后一次修改時間和If-Modified-Since的值進(jìn)行比較。
如果相等則返回 304 ,代表資源無更新,繼續(xù)使用瀏覽器緩存文件。
如果服務(wù)器的資源最后被修改時間大于If-Modified-Since的字段值,則重新返回資源,狀態(tài)碼為200。
在Nodejs中,可以通過fs.statSync(path).mtime獲取文件的最后修改時間。
注意:Last-Modified是秒級別的,如果在這一秒內(nèi)多次修改文件則Last-Modified不會改變,瀏覽器下次請求就會認(rèn)為資源沒有發(fā)生變化,這也是為什么會有ETag的原因。
Etag
Etag是服務(wù)器響應(yīng)請求時,返回包含在響應(yīng)頭的當(dāng)前資源文件的一個唯一標(biāo)識(由服務(wù)端生成)。
If-None-Match是客戶端再次發(fā)起該請求時,攜帶上次請求返回的唯一標(biāo)識Etag值。
服務(wù)器收到請求后,則會根據(jù)If-None-Match的值與該資源在服務(wù)器中計算出的Etag值做比較。
如果相等則返回304,代表資源無更新,繼續(xù)使用瀏覽器緩存文件。
如果不相等則重新返回資源文件,狀態(tài)碼為200。
優(yōu)點
緩解服務(wù)器端壓力,提升性能,優(yōu)化用戶體驗。
缺點
強緩存需要設(shè)置絕對時間或者相對時間,由于我們無法判斷具體多長時間資源會發(fā)生變化,就有可能導(dǎo)致資源更新后,該資源還處于緩存期間。
一個比較好的解決方案是:改變資源后給資源加上一個哈希路徑,同時把引用該資源的路徑改為變更后的路徑,讓瀏覽器主動放棄緩存,加載新資源。當(dāng)然,如果用戶沒有刷新頁面,還是會用舊的資源。