過去沒太研究過HTTP,最近有空,看了一些。本文主要討論瀏覽器緩存以及304狀態碼的一些知識,在這裏作一個分享,這裏先上一張HTTP請求流程圖:html
禁止緩存指的是緩存中不得存儲任何關於客戶端請求和服務端響應的內容。每次由客戶端發起的請求都會下載完整的響應內容。segmentfault
在請求頭中,Cache-Control: no-store
與Pragma: no-cache
均可以禁止緩存,瀏覽器
但二者也有區別,Pragma: no-cache
能夠兼容http 1.0
,而Cache-Control: no-store
是http 1.1
提供的。所以,Pragma: no-cache
能夠應用到http 1.0
和http 1.1
,而Cache-Control: no-store
只能應用於http 1.1
。緩存
是否檢查本地版本是否過時主要由Cache-Contro
的 no-cache
和must-revalidate
這兩個可選值控制,其中:服務器
no-cache
: 告訴瀏覽器、緩存服務器,無論本地副本是否過時,使用資源副本前,必定要到源服務器進行副本有效性校驗。must-revalidate
:告訴瀏覽器、緩存服務器,本地副本過時前,可使用本地副本;本地副本一旦過時,必須去源服務器進行有效性校驗。
想要知道本地副本是否過時,咱們就須要瞭解緩存的過時機制:網站
(1)、過時機制中,最重要的指令是 max-age=<seconds>
,它表示資源可以被緩的最大時間;它一般會和must-revalidate
一塊兒使用,使用起來就像下面這樣:spa
Cache-Control: max-age=60, must-revalidate
複製代碼
(2)、若是不含有max-age
屬性,則會去查看是否包含Expires屬性,,經過比較Expires的值和頭裏面Date屬性的值來判斷是否緩存還有效。代理
(3)、若是 max-age
和 expires
屬性都沒有,找找頭裏的 Last-Modified 信息。若是有,緩存的壽命就等於頭裏面 Date
的值減去Last-Modified
的值除以10(注:根據rfc2626其實也就是乘以10%)。code
若是本地副本沒有過時,則會直接重緩存中讀取資源,並返回200狀態碼。cdn
若是本地副本過時,則會進行到源服務器進行有效性校驗的前期準備。
首先,會在請求頭裏尋找If-None-Match字段,其值爲服務器上次返回的ETag響應頭的值:
若是請求頭裏沒有If-None-Match字段,則會在請求頭中尋找If-Modified-Since字段,其值爲服務器上次返回的Last-Modified響應頭中的日期值:
若是If-None-Match
與If-Modified-Since
都沒有,則會直接向服務器請求數據。
若是請求頭中帶有If-None-Match
或If-Modified-Since
,則會到源服務器進行有效性校驗,若是源服務器資源沒有變化,則會返回304;若是有變化,則返回200;
在Cache-Control
還有兩個值:private
與public
,其中:
public
指令表示該響應能夠被任何中間人(好比中間代理、CDN等)緩存。若指定了 public
,則一些一般不被中間人緩存的頁面(由於默認是 private
)(好比 帶有HTTP驗證信息(賬號密碼)的頁面 或 某些特定影響狀態碼的頁面),將會被其緩存。
而 private
則表示該響應是專用於某單個用戶的,中間人不能緩存此響應,該響應只能應用於瀏覽器私有緩存中。
HTTP協議 MDN segmentfault網站上'趙雍'的回答 '紫雲飛'的博客
原文地址 王玉略的我的網站