一個通常狀況下的例子:html
瀏覽器輸入url,第一次發送http請求的時候,確定是不會有緩存這一說的,直接從服務器讀取數據。
如下討論的是第二次之後的輸入相同的url,緩存是如何工做的。chrome
第一次返回http響應的時候, 若是響應中攜帶cache-control
或者expires
,這兩個字段,
則說明這個資源是設置了強制緩存,
什麼意思呢,就是第二次請求這個資源時,在瀏覽器端,先去判斷cache-control
或者expires
的值,
若是成立,則直接在緩存中獲取,不去發送http請求,典型表明200 OK(from memory cache)
。瀏覽器
那麼是怎麼進行判斷的呢,expires
是http1的標準,cache-control
是http1.1的標準。expires
指定資源的過時時間,瀏覽器第二次請求時,判斷本地時間是否超過了這個過時時間,
若是沒有超過,則直接從緩存中取數據,不去發送http請求到服務端,
若是超過過時時間,則發送http請求到服務端緩存
cache-control
中有個max-age
指令,
和expires
的意思差很少,也是指定過時時間,
可是和expires
不一樣的是,max-age
指定的值,是個相對值,相對於第一次請求的時間,
也就是說瀏覽器第二次請求時,若是相對於第一次請求的時間,
沒有超過max-age
指定的時間,則直接從緩存中取數據,不去發送http請求到服務端;
瀏覽器第二次請求時,若是相對於第一次請求的時間,
超過max-age
指定的時間,則須要發送http請求到服務端。服務器
http響應中若是同時包括expires
和cache-control
,兩個須要都知足,纔會從緩存中獲取資源。
實際中,用一個就能夠,cache-control
的優先級高於expires
。expires
是個相對於服務器的絕對時間,若是把本機的時間修改了,和服務器不一致,則不許確了,推薦用cache-control
就能夠。url
第一次返回http響應的時候, 若是響應中攜帶Etag
或者last-modified
,這兩個字段,
則也說明服務器端也但願這個資源被緩存。code
那麼是怎麼進行緩存操做的呢
強制緩存不成功,纔去判斷是否有協商緩存,此時須要發送http請求,
發送http請求時,若是第一次請求返回的響應中攜帶Etag
或者last-modified
,
則第二次請求頭會包含if-none-match
或者if-modified-since
,
第一次請求返回的響應中Etag
指令是響應數據的一個hash值,
第二次請求時,會將這個hash值給到if-none-match
,
而後在服務器端,計算數據的hash值,得出一個hash,判斷這個計算出的hash與if-none-match
的hash是否相等,
若是相等,則說明第二次請求的數據並無發生變化,
服務器端會返回304響應狀態碼,告訴瀏覽器端,直接取瀏覽器端的緩存;
若是不相等,服務器端返回200,生成新的Etag
值,返回新數據,給到瀏覽器。htm
if-modified-since
的目的和Etag
的目的同樣,他是個相對於服務器的絕對時間,
若是把本機的時間修改了,和服務器不一致,則不許確了,,若是把本機的時間修改了,則不許確了,推薦用Etag
就能夠。blog
以上是個正常流程,看一下其餘的狀況:
一、 第一次返回http響應的時候, cache-control
的max-age
爲0或者no-cache,
就是服務器端不但願瀏覽器直接讀取緩存,而是要經過發送http請求,經過Etag
或者last-modified
等指令去判斷是否讀取緩存。
這時候要麼返回200
,要麼返回304
,不會返回200 OK(from memory cache)
,
意思就是怎麼都要去服務器端去判斷一下內容有沒有更新,不容許直接讀取緩存,資源
二、 發送http請求的時候,若是帶有cache-control
的max-age
爲0,則爲瀏覽器不去判斷是否有緩存,直接發送http請求,
chrome刷新瀏覽器的時候,請求中會默認帶上cache-control
的max-age
爲0,
這種狀況就不會返回200 OK(from memory cache)
。