1. 程式人生 > 其它 >HTTP中有關快取的首部欄位有哪些?HTTP的瀏覽器快取機制?

HTTP中有關快取的首部欄位有哪些?HTTP的瀏覽器快取機制?

一、Last-Modified和If-Modified-Since

簡單地說,Last-Modified和If-Modified-Since都是用於記錄頁面最後修改時間的HTTP頭資訊,只是Last-Modified是由伺服器向客戶端傳送的HTTP響應頭If-Modified-Since則是由客戶端往伺服器傳送的請求頭

當再次請求本地存在的快取頁面時,客戶端會通過If-Modified-Since頭把瀏覽器快取在頁面的最後一次被伺服器修改的時間一起發到伺服器去,

伺服器會把這個時間與伺服器上實際檔案的最後修改時間進行比較,通過這個時間戳判斷客戶端的頁面是否是最新的:

  如果不是最新的,就返回HTTP狀態碼200和新檔案內容,客戶端收到之後,會丟棄舊檔案,把新檔案快取起來,並顯示到瀏覽器中;

  如果是最新的,則返回304告訴客戶端其本地快取的頁面是最新的,就直接把本地快取檔案顯示到瀏覽器中,這樣在網路上傳輸的資料量就會大大減少,同時也減輕了伺服器的負擔。

1、什麼是“Last-Modified”?

  在瀏覽器第一次請求某一個URL時,伺服器端的返回狀態是200,內容是你請求的資源,同時有一個Last-Modified的屬性標記此檔案在伺服器端最後被修改的時間,格式類似這樣:Last-Modified:Fri, 12 May 2010 18:53:33 GMT

  客戶端第二次請求此URL時,瀏覽器會向伺服器傳送If-Modified-Since報頭,詢問該時間之後檔案是否有被修改過:If-Modified-Since: Fri, 12 May 2010 18:53:33 GMT

  如果伺服器的資源沒有變化,則自動返回HTTP 304狀態碼,內容為空,這樣就節省了傳輸資料量。

  如果伺服器端程式碼發生改變或者重啟伺服器時,則重新發出資源,返回和第一次請求時類似,從而保證不向客戶端重複發出資源,也保證當伺服器有變化時,客戶端能夠得到最新的資源。

二、ETag和 If-None-Match

ETag和 If-None-Match是一種常用的判斷資源是否改變的方法。類似於Last-Modified和If-Modified-Since。

但是有所不同的是Last-Modified和If-Modified-Since只判斷資源的最後修改時間,而ETag和 If-None-Match可以是資源的任何屬性

,比如資源的MD5等。

ETag和 If-None-Match的工作原理是在HTTP Response Headers中新增ETags資訊。當客戶端再次請求該資源時,將在HTTP Request Headers中加入If-None-Match資訊(也就是ETags的值)。

如果伺服器驗證資源的ETags沒有改變(該資源的內容沒有改變),將返回一個304狀態;否則,伺服器將返回200狀態,並返回該資源和新的ETags。

1)什麼是“ETag”?

    伺服器為每個資源分配對應的ETag值,根據資源的內容得到其值當資源內容發生改變時,其值也會改變。以下是伺服器端返回的格式:

    ETag:"50b1c1d4f775c61:df3"

    客戶端的查詢更新格式是這樣的:

    If-None-Match:W/"50b1c1d4f775c61:df3"

    如果ETag沒有改變,則返回狀態304,這也和Last-Modified一樣。

擴充套件1:Last-Modified和ETags如何幫助提高效能?

    聰明的開發者會把Last-Modified和ETags請求的HTTP報頭一起使用,這樣可利用客戶端的快取。因為伺服器首先產生Last-Modified/Etag標記,伺服器可在稍後使用它來判斷頁面是否已經被修改。本質上,客戶端通過將該記號傳回伺服器要求伺服器驗證其(客戶端)快取。

擴充套件2:既然有了Last-Modified,為什麼還要用ETag欄位呢?

    1)某些檔案修改非常頻繁,比如在秒以下的時間內進行修改,If-Modified-Since能檢查到的粒度是秒級的,這種修改無法體現。

    2)一些檔案也許會週期性的更改,但是它的內容並不改變(僅僅改變修改的時間)【此時服務端資源內容並未改變,所以ETag值並不改變】,這個時候我們並不希望客戶端認為這個檔案被修改了,而重新GET;

    3)某些伺服器不能精確的得到檔案的最後修改時間。

3、Expires/Cache-Control(優先使用)

用來控制快取的失效日期,控制瀏覽器是直接從瀏覽器快取取資料還是重新發請求到伺服器取資料。

Expires是web伺服器響應訊息頭欄位,在響應HTTP請求時告訴瀏覽器在過期時間前瀏覽器可以直接從瀏覽器快取取資料,而無需再次請求。

Expires的一個缺點是,返回的到期時間是伺服器端的時間。這樣就存在一個問題,如果客戶端的時間與伺服器的時間相差很大(比如時間不同步,或者跨時區),那麼誤差就很大。

所以在HTTP1.1版開始,使用Cache-Control: max-age=(秒)替代。

當伺服器發出響應的時候,可以通過兩種方式來告訴客戶端快取請求:【通知客戶端是否可以快取該服務端返回的資源】

第一種是Expires,比如:Expires: Sun, 16 Oct 2016 05:43:02 GMT

    不過Expires有缺點,比如說,服務端和客戶端的時間設定可能不同,這就會使快取的失效可能並不能精確地按伺服器的預期進行。

第二種是Cache-Control,比如:Cache-Control: max-age=315360000

    這裡宣告的是一個相對的秒數,表示從現在起,315360000秒內快取都是有效的,這樣就避免了服務端和客戶端時間不一致的問題。

    但是Cache-Control是HTTP1.1才有的,不適用於HTTP1.0,而Expires既適用於HTTP1.0,也適用於HTTP1.1,所以說在大多數情況下,同時傳送這兩個頭回是一個更好的選擇,當用戶端兩種頭都能解析的時候,會優先使用Cache-Control。

過程如下:

  (1)客戶端請求一個頁面(A)。

  (2)伺服器返回頁面A,並再給A加上一個Last-Modified和ETag。 

  (3)客戶端展現該頁面,並將頁面連同Last-Modified和ETag的值一起快取。

  (4)客戶再次請求頁面A,並將上次請求時伺服器返回的Last-Modified和ETag的值一起傳遞給伺服器。

  (5)伺服器檢查該Last-Modified或ETag,並判斷出該頁面資源自上次客戶端請求之後還未被修改,直接返回響應304和一個空的響應體。

例項

1.首先在伺服器建立一個簡單的HTML檔案,用瀏覽器訪問一下,成功表示HTML頁面。Fiddler就會產生下面的捕獲資訊。

需要留意的是:

  (1)因為是第一次訪問該頁面,客戶端發請求時,請求頭中沒有If-Modified-Since標籤。

  (2)伺服器返回的HTTP狀態碼是200,併發送頁面的全部內容。

  (3)伺服器返回的HTTP頭標籤中有Last-Modified,告訴客戶端頁面的最後修改時間。

2.在瀏覽器中重新整理一下頁面,Fiddler就會產生下面的捕獲資訊。

需要注意的是:

  (1)客戶端發HTTP請求時,使用If-Modified-Since標籤,把上次伺服器告訴它的檔案最後修改時間返回到伺服器端了。

  (2)因為檔案沒有改動過,所以伺服器返回的HTTP狀態碼是304,沒有傳送頁面的內容。

3.用文字編輯器稍微改動一下頁面檔案,儲存。再用瀏覽器訪問一下,Fiddler就會產生下面的捕獲資訊。

需要注意的是:

  (1)客戶端發HTTP請求時,使用If-Modified-Since標籤,把上次伺服器告訴它的檔案最後修改時間返回到伺服器端了。

  (2)因為檔案被改動過,兩邊的時間不一致,所以伺服器返回的HTTP狀態碼是200,併發送新頁面的全部內容。

  (3)伺服器返回的HTTP頭標籤中有Last-Modified,告訴客戶端頁面的新的最後修改時間。

去期待陌生,去擁抱驚喜。