摘要:協商緩存則會向服務器請求確認資源是否過期。這也是緩存驗證的順序,先使用強緩存,后使用協商緩存。表明響應只能被單個用戶緩存,不能作為共享緩存即代理服務器不能緩存它可以緩存響應內容。設置緩存存儲的最大周期,超過這個時間緩存被認為過期單位秒。
為什么會有HTTP緩存?HTTP緩存的存在是因為web前端的性能瓶頸大部分的原因在于HTTP傳輸的時間耗費過長。如果能夠減少這種HTTP請求的時間,對網頁的性能來說是非常大的提升,對于用戶的體驗也能得到極大的改善。
HTTP緩存標識HTTP緩存可分為強緩存(Cache-Control和Expires)以及協商緩存(Etag和Last-Modified)。
強緩存和協商緩存的區別在于:如果命中強緩存,會直接從緩存中讀取資源,不向服務器請求。協商緩存則會向服務器請求確認資源是否過期。這也是緩存驗證的順序,先使用強緩存,后使用協商緩存。
下面則簡單介紹一下這兩種緩存類型的標識
Cache-ControlCache-Control設置有效期max-age的值是時間的相對值。
下面則簡單介紹Cache-Control常用的使用值:
value | description |
---|---|
public | 表明響應可以被任何對象(包括:發送請求的客戶端,代理服務器,等等)緩存。 |
private | 表明響應只能被單個用戶緩存,不能作為共享緩存(即代理服務器不能緩存它),可以緩存響應內容。 |
no-cache | 在發布緩存副本之前,強制高速緩存將請求提交給原始服務器進行驗證。 |
no-store | 緩存不應存儲有關客戶端請求或服務器響應的任何內容。 |
max-age= |
設置緩存存儲的最大周期,超過這個時間緩存被認為過期(單位秒)。與Expires相反,時間是相對于請求的時間。 |
must-revalidate | 緩存必須在使用之前驗證舊資源的狀態,并且不可使用過期資源。 |
proxy-revalidate | 與must-revalidate作用相同,但它僅適用于共享緩存(例如代理),并被私有緩存忽略。 |
若想了解更詳細的說明,可參考此鏈接:developer.mozilla.org/zh-CN/docs/…
ExpiresExpires 響應頭包含日期/時間, 即在此時候之后,響應過期。
Expires設置的值是一個絕對值。
Expires: Wed, 21 Oct 2015 07:28:00 GMTEtag
Etag HTTP響應頭是資源的特定版本的標識符。這可以讓緩存更高效,并節省帶寬,因為如果內容沒有改變,Web服務器不需要發送完整的響應。而如果內容發生了變化,使用ETag有助于防止資源的同時更新相互覆蓋(“空中碰撞”)。
Etag的值是根據資源文件內容生成的一個hash值。
Etag: 33a64df551425fcc55e4d42a148795d9f25f89d4Last-Modified
Last-Modified包含源頭服務器認定的資源做出修改的日期及時間。 它通常被用作一個驗證器來判斷接收到的或者存儲的資源是否彼此一致。由于精確度比 ETag 要低,所以這是一個備用機制。
Last-Modified的值是一個時間的絕對值。
Last-Modified: Wed, 21 Oct 2015 07:28:00 GMTHTTP緩存驗證規則 HTTP緩存的驗證順序
先使用強緩存(Cache-Control > Expires) 判斷資源是否過期;
若資源未過期則直接從緩存讀取,若資源過期則使用協商緩存;
使用協商緩存(Etag > Last-Modified)請求服務器確認資源有無修改(請求頭會帶上 If-None-Match 或 If-Modified-Since);
若資源無修改則返回 304 狀態碼告訴客戶端可讀取緩存;若資源已修改則返回 200 狀態碼重新獲取資源;
圖示:
圖片來源:www.cnblogs.com/xiaohuochai…
HTTP緩存驗證說明
以下的HTTP緩存驗證說明是基于假設請求存在4個緩存頭標記;
HTTP緩存是否過期,先判斷Cache-Control是否設置max-age或s-max-age,如果已設置則忽略Expires并且驗證是否過期,否則驗證Expires是否過期;其實按照MDN文檔的說明,Last-Modified也是可以計算出一個緩存時間;
下面是MDN文檔的說明:
對于含有特定頭信息的請求,會去計算緩存壽命。比如Cache-control: max-age=N的頭,相應的緩存的壽命就是N。通常情況下,對于不含這個屬性的請求則會去查看是否包含Expires屬性,通過比較Expires的值和頭里面Date屬性的值來判斷是否緩存還有效。如果max-age和expires屬性都沒有,找找頭里的Last-Modified信息。如果有,緩存的壽命就等于頭里面Date的值減去Last-Modified的值除以10(注:根據rfc2626其實也就是乘以10%)。
緩存時間計算公式:
expirationTime = responseTime + freshnessLifetime - currentAge
如果該緩存未過期,是不會向服務器發送請求的,而是直接從緩存中讀取,也就是我們可以從HTTP請求信息里得到的狀態碼 200 (from cache memory || from disk memory) ,如果緩存過期,則使用協商緩存;
先嘗試從內存中讀取,再嘗試從硬盤中讀取。
200 form memory cache 不訪問服務器,一般已經加載過該資源且緩存在了內存當中,直接從內存中讀取緩存。瀏覽器關閉后,數據將不存在(資源被釋放掉了),再次打開相同的頁面時,不會出現from memory cache。
200 from disk cache 不訪問服務器,已經在之前的某個時間加載過該資源,直接從硬盤中讀取緩存,關閉瀏覽器后,數據依然存在,此資源不會隨著該頁面的關閉而釋放掉下次打開仍然會是from disk cache。
使用協商緩存驗證緩存資源是否修改;Etag > Last-Modified,當存在Etag則使用Etag,否則使用Last-Modified;并且請求時會帶上特定的標識;
Etag 請求時會帶上 If-None-Match
Last-Modified 請求時會帶上 If-Modified-Since
當確認資源未修改時則返回 304 (Not Modified)告訴客戶端可以繼續使用緩存,否則返回200重新獲取新的資源。
HTTP緩存早期的時候只有Expires和Last-Modified,為什么后面又會出現Cache-Control和Etag呢?
先說說Expires和Cache-Control,Expires的值是一個準確的時間,比較的時候先根據返回頭的Date值比較判斷,但是若無Date頭信息返回則是根據客戶端的本地時間進行比較;本地時間因為各種因素影響,會存在各種不同的值,導致Expires緩存的時間并不是我們想要的效果。而Cache-Control設置max-age使用的相對值則相對來說控制粒度更精確了;并且Cache-Control的其他值則讓我們對于緩存的控制更加靈活。
再說說Last-Modified和Etag,Last-Modified的值也是一個準確的時間,精確到秒;使用時間來判斷資源是否修改則可能存在以下問題:
1秒內的修改可能不被檢查到,導致緩存無法更新;
資源可能只是多了幾個空格或無變化,但是Last-Modified的時間已經變化;
針對以上的問題所以有了Etag的存在,Etag是根據資源內容生成的hash值對比判斷資源是否更新,控制粒度比Last-Modified更加精確。
總結HTTP緩存的本質上是以空間換時間,緩存的存在是為了盡可能的減少HTTP請求次數和HTTP傳輸的內容大小,這也是前端性能優化中重要的一環。合理的設置頁面資源的緩存,有助你提升頁面的體驗。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/6779.html
摘要:基礎,超文本傳輸協議。不驗證通信方的身份,通信方的身份有可能遭遇偽裝。無法證明報文的完整性,報文有可能遭篡改。多路復用,支持單個連接多次請求,即連接共享,即每一個都是是用作連接共享機制的。 走在前端的大道上 本篇將自己讀過的相關 http/https 方法 文章中,對自己有啟發的章節片段總結在這(會對原文進行刪改),會不斷豐富提煉總結更新。 Web 基礎 HTTP(HyperText...
摘要:的選擇器允許單個線程監視多個輸入通道。一旦執行的線程已經超過讀取代碼中的某個數據片段,該線程就不會在數據中向后移動通常不會。 1、引言 很多初涉網絡編程的程序員,在研究Java NIO(即異步IO)和經典IO(也就是常說的阻塞式IO)的API時,很快就會發現一個問題:我什么時候應該使用經典IO,什么時候應該使用NIO? 在本文中,將嘗試用簡明扼要的文字,闡明Java NIO和經典IO之...
閱讀 2293·2021-11-24 09:39
閱讀 2535·2021-11-22 15:24
閱讀 2976·2021-09-02 09:48
閱讀 3010·2021-07-26 22:01
閱讀 1433·2019-08-30 11:09
閱讀 1673·2019-08-29 18:47
閱讀 601·2019-08-29 15:40
閱讀 2132·2019-08-29 15:22