我所知道的快取

BSOXDTDTPJHVCKFD發表於2017-12-25

我所知道的快取分為服務端快取和客戶端快取,客戶端快取就是瀏覽器快取,服務端快取分為CND快取和代理伺服器快取(eg: Nginx)。

瀏覽器快取

瀏覽器快取主要通過http中的header中的欄位來控制,分為強快取和協商快取。瀏覽器請求資源時當命中強快取,則從快取中讀取資源,強快取未命中,則進行協商快取,瀏覽器將請求發往伺服器,伺服器判斷可以走快取就返回304 Not Modified, 否則返回請求的資源。

強快取:response中的Expires或者Cache-Control

  • Expires:伺服器返回有個Date,表示在此時間段內,資源快取有效。瀏覽器請求資源時判斷當前客戶端時間是否晚於Expires,不晚則表示快取有效,命中強快取,讀取快取資源。

    Expirse是HTTP1.0提出的快取處理方案,因為是通過客戶端時間和服務時間進行比較,這樣當伺服器和客戶端存在很大的時區時,就會導致快取失效,同時也可以同過篡改客戶端時間導致快取失效或者錯亂,不是很可靠

我所知道的快取

  • Cache-Control: 可配置如下引數
 // 表明資源可以被瀏覽器、CDN、代理伺服器快取等任何物件快取
 Cache-Control: public 
 // 表明資源只能被瀏覽器快取
 Cache-Control: private 
 // 表明禁止強快取,只能走協商快取
 Cache-Control: no-cache 
 // 相對時間,表示從第一次收到請求後多久秒內走快取
 Cache-Control: max-age=<seconds> 
 // 跟max-age相同,但是在共享資源中(CDN或者代理伺服器)起作用。私有資源時忽略此引數
 Cache-Control: s-maxage=<seconds> 
複製程式碼

Cache-Control中max-age設定的是快取有效的相對時間,流程如下:

  1. 瀏覽器第一次請求資源a.js,伺服器返回資源以及response中的Cache-Control:max-age=??.

  2. 再次請求a.js時,判斷這次resquest的時間是否在有效期內(不知道瀏覽器判斷的時候是不是判斷本地快取最後一次修改的時間和當前的request的時間差??),是的化就命中快取。

    因為max-age是客戶端之間的相對時間判斷,都是客戶端時間進行比較,所以比Expires更有效,更安全,但是手動篡改客戶端時間依然可以導致快取失效 因此Cache-Control設定了max-age後就會覆蓋Expires。

協商快取:

    #response header
    // 伺服器返回資源最後修改時間,Date
    Last-Modified
    #resquest header
    // 瀏覽器再次請求資源時攜帶If-Modified-Since欄位。欄位的值就是上次response的Last-Modified的值
    If-Modified-Since
    #或者
    #response header
    // 伺服器返回MD5根據當前資源內容生成的一個摘要,資源內容不變,這個摘要的值就不會變
    ETag
    #resquest header
    // 瀏覽器再次請求資源時攜帶If-None-Match欄位。欄位的值就是上次response的ETag的值
    If-None-Match
複製程式碼

流程如下:

  1. 瀏覽器第一次請求資源a.js,服務端返回資源a.js和Last-Modified。
  2. 瀏覽器再次請求資源a.js,同時request的header中攜帶If-Modified-Since,值就是上次返回的Last-Modified
  3. 伺服器收到a.js的資源請求,通過request中的If-Modified-Since的時間和本地資源的最後修改時間進行對比,沒有變化將返回304 not modified,瀏覽器讀取本地快取。修改時間變化了,伺服器返回請求的資源,並在response的header中攜帶最新的Last-Modified。

ETag跟上面流程一樣,只是比較的不是資源最後修改的時間,而是資源的內容。

Last-Modified + If-Modified-Since的缺點

單一的時間比較,如果修改了資源但是資源的內容沒有發生變化,就會導致快取失效,這個是很不應該的。

總結: 瀏覽器(客戶端)快取主要是用於快取一些靜態資源

CDN快取

CDN快取,我個人的理解是,因為真正的伺服器只在一個地方,這樣對於各個地方的使用者,就存在有些距離遠的使用者訪問的時候慢一點,所以CDN就是別人的分佈在各地的專門存放快取資源的地方,這樣就可以讓各地的使用者訪問服務的時候都是走的最近的CDN伺服器。如果發現快取失效,則請求真正的伺服器,獲取到資源後快取在本地,並將資源返回給客戶端。

下面說正經的:CDN的全稱是Content Delivery Network,即內容分發網路。是架設在客戶端和伺服器之間的Cache層,客戶端請求資源時,具體CDN原理不是很懂,大致的意思就是CDN對域名解析進行了調整,然後返回一個CNAME,瀏覽器對CNAME進行解析後得到了CDN伺服器的ip,CDN伺服器上存在請求的資源就返回本地快取,不存在則CDN伺服器向真正的伺服器發出請求,獲得資源後快取在本地,並返回給客戶端,實現整個流程。

優點:CDN快取主要起到客戶端跟伺服器之前地域的問題,減少延時,分流作用,降低伺服器的流量,減輕伺服器壓力

參考資料:

http://www.cnblogs.com/lyzg/p/5125934.html http://imweb.io/topic/55c6f9bac222e3af6ce235b9 https://segmentfault.com/a/1190000006741200#articleHeader1 https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Cache-Control

相關文章