HTTP學習筆記(一) HTTP快取機制

2021-08-15 20:25:51 字數 3692 閱讀 9590

快取在應用開發中是乙個很重要的環節,利用好快取能夠有效地提公升使用者的體驗,加快使用者對資源的獲取效率。在http中,http定義了一套快取機制來指導客戶端對於資源的快取模式。

在http中,快取的方式分為兩種:強快取和協商快取。他們的區別在於強快取不會向伺服器發起請求,只要快取資源沒有過期,就會直接利用儲存在客戶端記憶體或硬碟中的快取資源;而協商快取則是無論快取資源是否過期,客戶端都要向伺服器發起乙個請求,用以向伺服器確認快取資源是否可用。

如今各大主流瀏覽器雖然都已經使用了http/1.1,但是還是不能排除有些使用者使用著舊的使用者**,上面執行的http版本仍是1.0的版本,所以了解http/1.0遺留下的快取字段還是有必要的。

pragma

pragma是http/1.0遺留下的乙個舊的字段,不過奇怪的是在如今的http/1.1的版本中,它仍然能夠起作用,而且優先順序還比http/1.1定義的cache-control欄位的優先順序要高;它的字段值唯一,只有乙個可用的值no-cache;當響應欄位中使用了pragma欄位時,就會指示客戶端,每次對該資源的訪問請求都該向伺服器發起乙個請求,而不應直接使用客戶端快取。

expires

pragma是用於禁止快取的字段,相對的就存在開啟快取的字段,也就是expires欄位。expires欄位的有效值是乙個gmt格式的時間字串,用以表示快取資源在這個日期之前都是有效的。不過,這個欄位的侷限性在於,這個時間字串表示的是伺服器的時間,如果客戶端的時間和伺服器的時間不一致的話,那麼就可能導致在客戶端上這個快取的有效期並不準確。expires在現代瀏覽器中主要都是用於相容使用了舊版本http/1.0的瀏覽器,在使用了http/1.1的瀏覽器中,它都被接下來要介紹的cache-control替代了。

由於expires存在的侷限性,在http/1.1裡,它就被新出現的cache-control欄位替代了。cache-control不像expires用乙個絕對的日期作為快取過期的憑證,而是使用快取時間策略,使用秒數來指示快取是否過期,這樣就能解決客戶端、伺服器時間不一致的問題。cache-control是乙個通用首部,其可用的字段值如下:

請求報文:

no-cache:表示客戶端通知**不打算使用快取資源而是要向伺服器發起乙個請求

no-store:表示任何內容都不會被快取在客戶端或internet臨時檔案中

max-age=delta-seconds:表示客戶端希望使用在存在時間不大於該值的快取資源

max-stale(=delta-seconds):表示客戶端通知**,其願意接受乙個過期的資源(其中括號中是乙個可選值,表示客戶端指示的可接受的最大過期時間)

min-fresh=delta-seconds:表示客戶端希望接受乙個在該時間內更新過的資源

no-transform:表示客戶端不希望接受到的資源被轉碼(比如壓縮)

only-if-cached:表示客戶端希望能只接受快取的資源(如果有),而不用向伺服器重新請求

其中delta-seconds的單位為秒。

響應報文:

no-cache:通知客戶端對該資源的請求都應該向伺服器發乙個請求,而不應直接使用快取

no-store:任何內容都不會被快取在客戶端或internet臨時檔案中(包括下文會提到的etag和last-modified)

max-age=delta-seconds:表示該資源的快取有效時間

s-maxage:同max-age,不過是用於共享資源的(也就是**)

public:表示該快取資源可以共享,也就是中間**也可以快取該資源

private:該資源只能夠快取在私人客戶端上

must-revalidate:告知客戶端對該資源的驗證請求必須向源伺服器發起驗證,而不是**

proxy-revalidate:與must-revalidate類似,但只用於**伺服器

no-transform:指示客戶端在快取時不應對資源的實體資料做任何改變

在使用cache-control時,我們可以按需求合理的組合上述字段值,比如:

cache

-control:max

-age

=60,must-revalidate

這段字段表示快取的有效時間是60秒,在這段時間內客戶端可以不用向伺服器發起請求,直接使用快取資源;而過了60秒以後,客戶端再請求資源一定要向源伺服器發起請求進行快取驗證。

再如:

cache

-control:no-cache,no-store,must-revalidate

這段字段用於禁止客戶端對資源進行快取,並且一定要向源伺服器發起請求。其中no-cache,no-store同時使用可以用來禁止不同瀏覽器使用後退按鈕的時候使用快取資源的行為。(ie中使用no-cache即可禁止這一行為,但是在firefox中需要使用no-store才可禁止)

last-modified和if-modified-since

last-modified欄位是乙個響應首部字段,用於指示該資源在伺服器上的最後一次修改時間;與之相對的是if-modified-since,乙個請求首部字段,用於通知伺服器如果該資源在該字段表示的時間之後有修改的話,就應返回新的資源;否則,應該允許客戶端使用快取。這兩個欄位的值都是乙個gmt格式的時間字串。

伺服器接受到含有if-modified-since的報文以後,會比較該值與資源的last-modified,如果last-modified小於或等於if-modified-since,伺服器就會返回304狀態碼(not modified),並不會附加實體內容,指示客戶端可以繼續使用快取;否則,就會返回200狀態碼,將新的資源作為實體一併返回。

一般來說,客戶端在接收到帶有last-modified的響應報文後,會將該時間與資源一同儲存在快取當中,在下次向伺服器發起請求時,就會將該時間值取出並設定為if-modified-since的值一併傳送給伺服器。

這種模式的缺點在於,last-modified的單位是秒,所以如果乙份資源在一秒內經過了多次改變的話,last-modified是無法檢測到這種頻率的變化的;而且,如果有些資源是週期性改變的,但是實際上他們的內容沒有變,這種情況下last-modified還是會變化,那麼客戶端就會請求乙份與快取內容沒有差異的資源。

etag與if-none-matched

為了彌補上述的last-modified存在的缺陷,http/1.1還存在另一種實現協商快取的機制:etag。etag是伺服器上乙份資源的唯一標識,生成這個etag的方式不是唯一的,可以是用md5演算法生成的,也可以是乙個根據內容生成的hash值。由於etag是根據檔案內容生成的,所以只要檔案的內容不變,etag就不會變;而如果乙份檔案在1秒內經歷了多次改變,那麼etag也會檢測到這一變化生成新的etag值。

伺服器在將帶有etag的響應報文傳送給客戶端後,客戶端會將該etag值和資源一同儲存在快取當中,在下次向伺服器發起請求的時候,就會將該etag值取出並設定為if-none-matched的值傳送給伺服器,伺服器對比該字段和該資源的etag值,如果相等,則返回304;否則,返回200

etag和last-modified的取捨

etag雖然能彌補last-modified的許多缺陷,不過生成etag是要消耗伺服器資源的,所以對於改動不那麼頻繁的檔案,我們未必一定要使用etag,只使用last-modified也未嘗不可。

在響應報文中使用vary頭部,可以指示客戶端對於後續的請求,是使用快取中的資源還是向源伺服器發起乙個新的請求。當快取伺服器收到乙個請求,只有當前的請求和原始(快取)的請求頭跟快取的響應頭里的vary都匹配,才能使用快取的響應。比如:

學習筆記 http快取機制

快取機制 快取校驗 對比快取 快取判斷優先順序 示例總結 參考資料 不請求網路資源,資源在記憶體當中,一般字型 會存在記憶體當中 不訪問伺服器,直接讀快取,從記憶體中讀取快取。此時的資料時快取到記憶體中的,當kill程序後,也就是瀏覽器關閉以後,資料將不存在。statuscode 200 不請求網路...

http學習 http的快取控制

由於請求 應答模式的通訊成本比較高,所以有必要將某些資料進行快取,從而節省頻寬。快取是優化系統效能的重要手段,http 傳輸的每乙個環節中都可以有快取 2.1 快取控制的流程 瀏覽器發現快取無資料,於是傳送請求,向伺服器獲取資源 伺服器響應請求,返回資源,同時標記資源的有效期 瀏覽器快取資源,等待下...

HTTP快取筆記(1)

筆記來自 mdn 主要有兩種,私有快取 private caches 或者共享快取 shared caches 快取示意圖 快取控制頭cache control headercache control no store,cache control no cache,no store,must rev...