HTTP緩存 - 強緩存/協商緩存/瀏覽器刷新

Web緩存:

數據庫緩存、服務器端緩存(代理服務器緩存、CDN 緩存)、瀏覽器緩存css

瀏覽器緩存:

HTTP 緩存、indexDB、cookie、localstorage 等等html

HTTP緩存

  • 強制緩存的優先級高於協商緩存
  • 強緩存:命中緩存不須要和服務器端發生交互
  • 協商緩存:不論是否命中都要和服務器端發生交互
  • 流程:

clipboard.png

強緩存

  • Expiresnode

    • 定義:緩存過時的時間,超過了這個時間點就表明資源過時
    • 缺點:服務器時間,客戶端時間可隨意修改
    • HTTP/1.0 的標準
  • Cache-Control算法

    • 由多個字段組合而成數據庫

      • max-age 指定一個時間長度,在這個時間段內緩存是有效的,單位是s(相對時間)
      • no-store 禁止緩存,每次請求都要向服務器從新獲取數據
      • no-cache : max-age = 0仍然緩存,可是走協商緩存
      • public 代表響應能夠被任何對象(發送請求的客戶端、代理服務器等等)Public 設置咱們能夠將 Http 響應數據存儲到本地,但此時並不意味着後續瀏覽器會直接從緩存中讀取數據並使用- 沒法肯定本地緩存的數據是否可用(可能已經失效)須要配合使用
      • private 代表響應只能被單個用戶(多是操做系統用戶、瀏覽器用戶)緩存,是非共享的,不能被代理服務器緩存
    • 緩存數據標記爲已過時只是告訴客戶端不能再直接從本地讀取緩存了,還可能被再次用到(協商緩存)
    • cache-control使用

clipboard.png

  • Cache-Control 的優先級更高,覆蓋expire

協商緩存

瀏覽器第一次請求數據以後會將數據和響應頭部的緩存標識存儲起來。再次請求時會帶上存儲的頭部字段,服務器端驗證是否可用。若是返回 304 Not Modified,表明資源沒有發生改變可使用緩存的數據,獲取新的過時時間。反之返回 200 就至關於從新請求了一遍資源並替換舊資源瀏覽器

  • Last-modified(響應頭)/If-Modified-Since(請求頭)緩存

    • 服務器端收到帶 If-Modified-Since 的請求後會去和資源的最後修改時間對比。若修改過就返回最新資源,狀態碼 200,若沒有修改過則返回 304
    • 注意: Last-modified 要記得配合 Expires/Cache-Control 使用,不設置,瀏覽器會有本身的算法來推算出一個時間緩存該文件多久,不一樣瀏覽器得出的時間不同(根據響應頭中2個時間字段 Date 和 Last-Modified 之間的時間差值,取其值的10%做爲緩存時間週期。)
  • Etag/If-None-Match服務器

    • 由服務器端上生成的一段 hash 字符串,第一次請求時響應頭帶上 ETag: abcd,以後的請求中帶上 If-None-Match: abcd,服務器檢查 ETag,返回 304 或 200
  • last-modified 和 Etag 區別cookie

    • 某些服務器不能精確獲得資源的最後修改時間,這樣就沒法經過最後修改時間判斷資源是否更新。
    • Last-modified 只能精確到秒。
    • 一些資源的最後修改時間改變了,可是內容沒改變,使用 Last-modified 看不出內容沒有改變。
    • Etag 的精度比 Last-modified 高,屬於強驗證,要求資源字節級別的一致,優先級高。若是服務器端有提供 ETag 的話,必須先對 ETag 進行 Conditional Request
    • Etag的值是須要服務器計算的且計算複雜,會消耗性能,視具體狀況而定

實際使用

考慮緩存的內容:
  • css樣式文件
  • js文件
  • logo、圖標
  • html文件
  • 能夠下載的內容
一些不該該被緩存的內容:
  • 業務敏感的 GET 請求
不常常改變的文件
  • 給 max-age 設置一個較大的值,通常設置 max-age=31536000(一年)
  • 文件名稱添加版本號、hash 值
可能常常須要變更的文件:
  • Cache-Control: no-cache / max-age=0

瀏覽器幾種刷新方式對緩存的影響

一、在URI輸入欄中輸入而後回車工具

200 OK (from cache),瀏覽器發現該資源已經緩存了並且沒有過時(經過Expires頭部或者Cache-Control頭部),沒有跟服務器確認,而是直接使用了瀏覽器緩存的內容。其中響應內容和以前的響應內容如出一轍

二、F5/點擊工具欄中的刷新按鈕/右鍵菜單從新加載

不管如何都發一個HTTP Request給Server,即便先前的響應中有Expires頭部

Cache-Control: max-age=0 // Chrome強制加上的
If-Modified-Since: Fri, 15 Jul 2016 04:11:51 GMT

三、Ctl+F5

完全的從Server拿一份新的資源過來

還須要添加一些HTTP Headers。按照HTTP/1.1協議,Cache不光只是存在Browser終端,從Browser到Server之間的中間節點(好比Proxy)也可能扮演Cache的做用
在Chrome 51 中會包含兩個頭部信息, 做用就是讓中間的Cache對這個請求失效,這樣返回的絕對是新鮮的資源。

Cache-Control: no-cache
Pragma: no-cache
Cache-Control: no-cache

總結

  • 四種緩存的優先級:cache-control > expires > etag > last-modified**
  • cache-control:設置過時的時間長度(秒),在這個時間範圍內,瀏覽器請求都會直接讀緩存
  • expires:在 http 頭中設置一個過時時間,在這個過時時間以前,瀏覽器的請求都不會發出,而是自動從緩存中讀取文件,除非緩存被清空,或者強制刷新
  • etag / if-none-match:服務器端返回資源時,若是頭部帶上了 etag,那麼資源下次請求時就會把值加入到請求頭 if-none-match
  • last-modified / if-modified-since:服務器端返回資源時,若是頭部帶上了 last-modified,那麼資源下次請求時就會把值加入到請求頭 if-modified-since

clipboard.png

補充:協商緩存在node的實現

相關文章
相關標籤/搜索