HTTP請求中的緩存(cache)機制

當資源第一次被訪問的時候,HTTP頭部以下html

(Request-Line) GET /a.html HTTP/1.1
Host    127.0.0.1
User-Agent  Mozilla/5.0 (X11; U; Linux i686; zh-CN; rv:1.9.0.15)Gecko/2009102815 Ubuntu/9.04 (jaunty) Firefox/3.0.15
Accept             text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language     zh-cn,zh;q=0.5
Accept-Encoding     gzip,deflate
Accept-Charset      gb2312,utf-8;q=0.7,;q=0.7
Keep-Alive          300
Connection          keep-alive瀏覽器

HTTP返回頭部以下緩存

(Status-Line)      HTTP/1.1 200 OK
Date                Thu, 26 Nov 200913:50:54 GMT
Server              Apache/2.2.11 (Unix)PHP/5.2.9
Last-Modified       Thu, 26 Nov 2009 13:50:19 GMT
Etag                「8fb8b-14-4794674acdcc0″
Accept-Ranges       bytes
Content-Length      20
Keep-Alive          timeout=5, max=100
Connection          Keep-Alive
Content-Type        text/html服務器

當資源第一次被訪問的時候,http返回200的狀態碼,並在頭部攜帶上當前資源的一些描述信息,如網絡

Last-Modified     // 指示最後修改的時間
Etag                     // 指示資源的狀態惟一標識
Expires               // 指示資源在瀏覽器緩存中的過時時間app

接着瀏覽器會將文件緩存到Cache目錄下,並同時保存文件的上述信息spa

當第二次請求該文件時,瀏覽器會先檢查Cache目錄下是否含有該文件,若是有,而且還沒到Expires設置的時間,即文件尚未過時,那麼此時瀏覽器將直接從Cache目錄中讀取文件,而再也不發送請求orm

若是文件此時已通過期,則瀏覽器會發送一次HTTP請求到WebServer,並在頭部攜帶上當前文件的以下信息xml

If-Modified-Since  Thu, 26 Nov 2009 13:50:19 GMT
If-None-Match       」8fb8b-14-4794674acdcc0″htm

即 把上一次修改的時間,以及上一次請求返回的Etag值一塊兒發送給服務器。服務器在接收到這個請求的時候,先解析Header裏頭的信息,而後校驗該頭部信 息。 若是該文件從上次時間到如今都沒有過修改或者Etag信息沒有變化,則服務端將直接返回一個304的狀態,而再也不返回文件資源,狀態頭部以下

(Status-Line)      HTTP/1.1 304 Not Modified
Date                Thu, 26 Nov 200914:09:07 GMT
Server              Apache/2.2.11 (Unix)PHP/5.2.9
Connection          Keep-Alive
Keep-Alive          timeout=5, max=100
Etag                「8fb8b-14-4794674acdcc0″

這樣,就可以很大程度上減小網絡帶寬以及提高用戶的瀏覽器體驗。 固然,若是服務器通過匹配發現文件修改過了,就會將文件資源返回,並帶上新文件狀態信息。

 

基本字段

Pragma

Pragma頭域用來包含實現特定的指令,最經常使用的是Pragma:no-cache。

在HTTP/1.1協議中,它的含義和Cache- Control:no-cache相同。

Expires

文件在本地緩存的過時時間,若是瀏覽器發現緩存中的文件沒有過時,則不發送請求(有例外,後面介紹)

Cache-Control

Cache-Control指定請求和響應遵循的緩存機制。在請求消息或響應消息中設置 Cache-Control並不會修改另外一個消息處理過程當中的緩存處理過程。

請求時的緩存指令包括no-cache、no-store、max-age、 max-stale、min-fresh、only-if-cached,響應消息中的指令包括public、private、no-cache、no- store、no-transform、must-revalidate、proxy-revalidate、max-age。

各個消息中的指令含義以下:   

Public指示響應可被任何緩存區緩存。

Private指示對於單個用戶的整個或部分響應消息,不能被共享緩存處理。這容許服務器僅僅描述當用戶的部分響應消息,此響應消息對於其餘用戶的請 求無效。   

no-cache指示請求或響應消息不能緩存。   

no-store用於防止重要的信息被無心的發佈。在請求消息中發送將使得請求和響應消息都不使用緩存。   max-age指示客戶機能夠接收生存期不大於指定時間(以秒爲單位)的響應。   

min-fresh指示客戶機能夠接收響應時間小於當前時間加上指定時間的響應。   

max-stale指示客戶機能夠接收超出超時期間的響應消息。若是指定max-stale消息的值,那麼客戶機能夠接收超出超時期指定值以內的響應消息。

 

Etag/If-None-Match

一對驗證文件實體的標記 「Entity Tag」的響應/請求頭 Apache中,ETag的值,默認是對文件的索引節(INode),大小(Size)和最後修改時間(MTime)進行Hash後獲得的

Last-Modified/If-Modified-Since

一對驗證文件的修改時間的響應/請求頭

Expires、 Cache-Control、Last-Modified、ETag是RFC2616(HTTP/1.1)協議中和網頁緩存相關的幾個字段。 前兩個用來控制緩存的失效日期,瀏覽器可經過它來斷定,需不須要發出HTTP請求; 後兩個用來驗證網頁的有效性,服務器端利用它來驗證這個文件是否須要從新返回Last-Modified VS Etag

既然有了Last-Modified,爲何還要用ETag字段呢?由於若是在一秒鐘以內對一個文件進行兩次更改,Last-Modified就會不正確。所以,HTTP/1.1利用Entity Tag頭提供了更加嚴格的驗證。

不一樣的狀況

上面描述的是一個普通的瀏覽器緩存狀態,在實際應用中,如頁面跳轉(點擊頁面連接跳轉,window.open,在地址欄敲回車,刷新頁面)等操做,會有一些區別

 

普通頁面跳轉

普通頁面跳轉包括連接點擊跳轉,用js腳本打開新頁面(window.open) 無緩存狀況下,請求會返回全部資源結果 設置Expires而且未過時時,瀏覽器將不會發出http請求 若是Expires過時,則會發送相應請求,並附帶上Last-Modifed等信息,供服務器校驗

頁面刷新(F5)

這種狀況一下,通常會看到不少304的請求,就是說即使資源設置了Expires且未過時,瀏覽器也會發送相應請求 IE和FF稍有區別 IE:

If-Modified-Since  Wed, 18 Nov 2009 15:54:52 GMT
If-None-Match   」2360492659″
Pragma: no-cache    // 禁止緩存

FF:

If-Modified-Since  Wed, 18 Nov 2009 15:54:52 GMT
If-None-Match   」2360492659″
Cache-Control   max-age=0   // 文件當即過時

強制刷新(Ctrl+F5)

效果和無緩存時候一致,返回200的結果

 

經常使用META的禁用緩存的方法

 

<META HTTP-EQUIV="Pragma"CONTENT="no-cache">

<META HTTP-EQUIV="Cache-Control"CONTENT="no-cache">

<META HTTP-EQUIV="Expires"CONTENT="0">

相關文章
相關標籤/搜索