天天看點

HTTP協定緩存機制的應用

緩存的目 的是減少相應延遲 和 減少網絡帶寬消耗, 比如 css、 js、圖檔這類靜态資源應該進行緩存。

實際項目 一般使用反向代理伺服器(如 nginx、 apache 等) 進行緩存。

關鍵字:

cache-control, expire, if-none-match, if-modified-since, etag, last-modified

請求處理過程:

當一個使用者發起一個靜态資源請求的時候,浏覽器會通過以下幾步來擷取資源

1.本地緩存階段:先在本地查找該資源,如果有發現該資源,而且該資源還沒有過期,就使用這一個資源,完全不會發送http請求到伺服器

2.協商緩存階段:如果在本地緩存找到對應的資源,但是不知道該資源是否過期或者已經過期, 則發一個http請求到伺服器,然後伺服器判斷這個請求,如果請求的資源在伺服器上沒有改動過,則傳回304, 讓浏覽器使用本地找到的那個資源

3.緩存失敗階段:當伺服器發現請求的資源已經修改過,或者這是一個新的請求(在本來沒有找到資源),伺服器則傳回該資源的資料,并且傳回200, 當然這個是指找到資源的情況下,如果伺服器上沒有這個資源,則傳回404

經過上面的流程整理,我們會有以下幾個問題需要處理.

1.本地緩存階段,如何判斷資源在本地是否過期?

2.協商緩存階段,如何判斷本地資源是否和伺服器的資源是否一樣?

expire:

如果apache開啟了expire子產品, 當浏覽器發送該資源請求的時候, apache傳回資源的同時,會傳回一個名為expire的http頭,expire頭的内容是一個時間值, 這一個值就是資源在本地的過期時間, 這個值會存在本地.

也就是說,在本地緩存階段,在本地找到了一個對應的資源值,而且目前時間還沒超過資源的過期時間, 那麼就直接使用這一個資源,不會發送http請求.

cache-control:

cache-control是http協定中常用的頭部之一,顧名思義, 他是負責控制頁面的緩存機制,如果該頭部訓示緩存, 緩存的内容也會存在本地, 操作流程和expire相似,但也有不同的地方, cache-control有更多的選項, 而且也有更多的處理方式.

該頭部有過個值,下面我們來看下各個值的作用

1.public

訓示響應可被任何緩存區緩存。

2.private

訓示對于單個使用者的整個或部分響應消息,不能被共享緩存處理。這允許伺服器僅僅描述當使用者的部分響應消息,此響應消息對于其他使用者的請求無效。

3.no-cache

訓示請求或響應消息不能緩存

4.no-store

用于防止重要的資訊被無意的釋出。在請求消息中發送将使得請求和響應消息都不使用緩存

5.max-age

訓示客戶機可以接收生存期不大于指定時間(以秒為機關)的響應。

6.no-transform

不允許轉換存儲系統

7.must-revalidate

使得用戶端再次浏覽目前頁時必須發送相關 http 頭資訊到伺服器進行驗證,然後才決定是否加載用戶端本地 cache

if-modified-since 和 last-modified:

當apache接收到一個資源請求(假設是使用者是第一次通路,沒有任何緩存), 伺服器傳回資源的同時,還會發送一個last-modified的http響應頭, last-modified響應頭的内容值是該資源在伺服器上最後修改的時間.浏覽器接受到這個http頭後,會

把其内容值和資源同時儲存起來.

當使用者第二發送資源請求(假設這裡expire沒有生效或者已經過期), 浏覽器在本地找到了一個相同的資源,但是不能确定該資源是否和伺服器上的一樣(有可能在兩次通路期間,伺服器上的資源已經被修改過),此時浏覽器發送請求的時候,請求頭内會

附帶一個if-modified-since的請求頭, 這個頭部的内容就是上一次last-modified傳回的值, 伺服器把這個頭的值和請求資源的最後修改時間對比,如果兩個值相同,則認為資源沒有修改,将會傳回304,讓浏覽器使用本地資源.否則伺服器将傳回資源,而且

傳回200狀态

if-none-match 和 etag:

其實這兩個頭部和if-modified-since, last-modified的工作原理是一樣的, if-none-match作為請求頭, etag作為響應頭.既然工作原理一樣, 為什麼etag這對頭部會出現呢?

原因在于, last-modified請求頭的内容是以檔案最後修改的時間作為對比的,但是unix系統裡面, 檔案修改的時間隻儲存到了秒. 如果某些應用記憶體在1秒内對檔案做了多次修改,這樣last-modified是不能完成比較功能的.是以要引入一個新的機制(原因可能不止這一個);

etag的值一般由3個數值組成,資源的inode值, 最後修改時間, 資源大小,以16進制組成一個字元串, 例如:1a-182b-10f; 但這個格式不是固定的, 隻要保證該值的唯一性,但不限格式.

浏覽器中的操作對緩存的影響:

1.強制重新整理 – 當按下ctrl+f5來重新整理頁面的時候, 浏覽器将繞過各種緩存(本地緩存和協商緩存), 直接讓伺服器傳回最新的資源;

2.普通重新整理 – 當按下f5來重新整理頁面的時候,浏覽器将繞過本地緩蹲來發送請求到伺服器, 此時, 協商緩存是有效的

3.回車或轉向 – 當在位址欄上輸入回車或者按下跳轉按鈕的時候, 所有緩存都生效

cache-control 和 expire:

1.兩者都是控制本地緩存的頭部兩者同時存在的時候

2.expire會被cache-control的max-age覆寫

3.expire的值是一個确定的日期, 而max-age的值是一個以秒為機關的數字通路, 表示生存時間.

4.expire隻針對靜态資源, 而cache-control針對所有頁面,但預設為所有的動态頁面不緩存(例如php頁面).

pragma 和 cache-control:

pragma是http/1.0實作的頭部, pragma的值會出現在頁面meta标簽的http-equiv屬性中,以此來控制頁面緩存

cache-control是http/1.1實作的頭部,在http/1.0下不相容.

if-modified-since 和 if-none-match的優先級:

伺服器會優先驗證if-modified-since請求頭,再驗證if-none-match,但是必須要兩者頭通過驗證的時候才傳回304,其中一個驗證失敗,都将傳回新資源和200狀态;