Web緩存知多少(緩存機制和數據存儲)

Web 緩存有不少種,好比數據庫緩存、代理服務器緩存、CDN 緩存,以及瀏覽器緩存。html

瀏覽器緩存指的是將緩存文件保存在客戶端,通常是經過 HTTP 進行緩存。算法

HTTP 緩存機制

HTTP/1.1 標準中固定了 HTTP 緩存的兩種方式: expiration 機制 和 validation 機制。前者是經過減小服務器和瀏覽器的循環次數,後者經過只響應頭部信息較少網絡帶寬。(有些參考資料,將前者稱爲強緩存,後者稱爲協商緩存)chrome

強緩存優先級高於協商緩存,也就是說,當執行強緩存的規則,緩存生效,則再也不執行協商緩存。數據庫

expiration Model -- 強緩存

expiration 機制經過 ExpiresCache-Control 兩個字段來標明失效規則。瀏覽器

Expires緩存

Expires 的值爲服務器返回的到期時間,即下一次請求時,請求時間小於服務器返回的到期時間,直接使用緩存數據。可是因爲客戶端和服務器可能有時間差,會致使較大的緩存命中偏差,因此 HTTP/1.1 使用了 Cache-Control 替代。安全

Cache-Control服務器

Cache-Control 是很是重要的規則。取值以下:cookie

  • private: 默認取值,表示客戶端能夠緩存
  • public: 客戶端和代理服務器均可以緩存
  • max-age: 緩存內容會在 xxx 秒後失效
  • no-cache: 緩存前確認必須先確認其有效性
  • no-store: 全部內容都不會緩存

注意,Cache-Control 是一個通用的首部字段。因此,取值對客戶端和服務器端含義會有所不一樣。網絡

應用 HTTP/1.1 版本的緩存服務器同時存在 Expires 首部字段的狀況時,會優先處理 max-age 指令,而忽略 Expires 首部字段。

強緩存請求數據流程以下: 客戶端向緩存服務器(緩存數據庫)請求數據,若是有緩存數據且未失效,則返回數據。若是沒有緩存數據或緩存數據失效,則向服務器請求數據,服務器返回數據和緩存規則,客戶端收到並將數據和緩存規則存入緩存。

validation Model -- 協商緩存

協商緩存的方式是客戶端發送請求驗證緩存標識所對應的數據是否失效,若是服務器判斷數據有效,則返回一個 304 狀態碼(即報文首部和狀態行),而不用返回報文主體。協議中規定了兩種緩存標識。

Last-Modified/If-Modified-Since

客戶端第一次請求服務器時,服務器在響應報文的首部經過 Last-Modified 字段告知瀏覽器資源的最後修改時間。

再次請求時,客戶端在請求報文的首部添加 If-Modified-Since 字段,該字段的值是上次請求時,服務器返回的 Last-Modified 的值。

服務器收到請求發現有 If-Modified-Since 則與被請求資源的最後修改時間進行比對,若資源的最後修改時間大於 If-Modified-Since 所提供的值,說明資源被改動過,則響應資源內容,返回狀態碼 200。不然,說明資源沒有被改動,則返回 304,告知瀏覽器可使用所保存的 cache。

Etag/If-None-Match 優先級高於 Last-Modified/If-Modified-Since

客戶端第一次請求服務器時,服務器在響應報文的首部經過 Etag 字段告知瀏覽器當前資源在服務器的惟一標識(生成規則由服務器決定)。

同理,再次請求時,緩存數據的惟一標識被添加到請求報文的 If-None-Match 字段中。

服務器收到請求發現有 If-None-Match 則與被請求資源的惟一標識進行比對,不一樣,說明資源被修改過,返回 200。相同,則說明資源未被修改,返回 304。

爲何須要 Etag?

Etag 的出現是爲了解決 Last-Modified/If-Modified-Since 比較難以解決的問題。好比:

  • 一些文件會週期性地更改,可是內容並不會改變,只是改變修改時間,這個時候咱們不太須要客戶端認爲文件內容被修改過了,而請求資源
  • 某些文件修改很是頻繁(指的是內容),好比每秒以內修改了屢次,If-Modified-Since 能檢查到的粒度是秒級,這種修改可能致使沒法斷定。

因此,Etag 的優先級高於 Last-Modified 也是應該的。可是,性能上,Etag 要遜於 Last-Modified,由於 Last-Modified 指記錄修改的時間值,而 Etag 的值須要算法計算一個 hash 值。

HTTP 緩存過程總結

  1. 瀏覽器第一次加載資源,服務器返回 200,並將數據和緩存規則存入緩存。
  2. 再次請求資源時,若是當前時間和上一次返回 200 的時間差不超過 Cache-Control 設置的 max-age,則沒有過時,命中緩存(若是瀏覽器不支持 HTTP/1.1,則用 expires 判斷是否過時)。若是時間過時,則向服務器發送 If-None-Match 和 If-Modified-Since 請求。
  3. 服務器收到請求,首先根據 Etag 的值判斷被請求的文件有沒有被修改,Etag 值一致,則命中協商緩存,返回304;若是不一致,返回新的資源的緩存規則和狀態碼,並返回 200。
  4. 若是服務器收到的請求沒有 Etag 值,則將 If-Modified-Since 和被請求的文件的最後修改時間作對比,一致則命中協商緩存,返回 304;不然返回新的 Last-Modified 和數據,返回 200。

用戶操做對緩存的影響

對於一下操做,如地址欄回車、頁面連接跳轉、新開窗口、前進和回退,兩種機制( expires/validation )都是有效的。

F5 刷新操做,Expires/Cache-Control 是無效的,Last-Modified/Etag 是有效的,也就是說強制協商緩存。

Ctrl + F5 強制刷新,二者都是無效的。

抓包工具: Fiddler

查看 chrome 緩存 chrome://view-http-cache/

參考: 完全弄懂HTTP緩存機制及原理


HTML5 應用緩存

應用緩存(application cache),簡稱 appcache,是專門爲開發離線 Web 應用設計的。它是從瀏覽器的緩存中分出來的一塊緩存區,使用一個 manifest 文件,列出要下載和緩存的資源。

第二步, 在須要離線使用的頁面中添加 manifest 屬性,用於指定緩存清單文件的路徑。好比:

<html manifest="/offline.manifest">
複製代碼

數據存儲

隨着 Web 應用的出現,也產生了可以直接在客戶端上存儲用戶信息能力的要求。

Cookie 是在客戶端存儲數據的其中一種選項。

Cookie

Cookie 的工做機制是用戶識別及狀態管理。它是怎樣工做的呢?好比,當要對某個用戶進行識別的時候,服務器對任意的 HTTP 請求發送 Set-Cookie 首部字段做爲響應的一部分。

HTTP/1.1 200 OK
Content-type: text/html
Set-Cookie: name=value
...
複製代碼

這以後,瀏覽器的每一個請求都添加 Cookie 字段將信息發送回服務器。服務器就知道你是屬於哪一個用戶了。

GET /index.html HTTP/1.1
Cookie: name=value
...
複製代碼

Set-Cookie 字段的屬性

  • name 名稱 一個惟一肯定的 cookie 的名稱,名稱必須被 URL 編碼
  • value 值 存儲在 cookie 中的字符串的值。值必須被 URL 編碼
  • domain 域名 肯定 cookie 有效的域,全部向該域發送的請求中都包含這個 cookie 信息
  • path 路徑 對於制定域中的那個路徑,才應該向服務器發送 cookie
  • expire 失效時間
  • secure 安全標識 指定後,cookie 只能在使用 SSL 鏈接時(即HTTPS通訊時)才發送到服務器
  • HttpOnly 它使得附加在 HttpOnly 屬性後的 Cookie 內容沒法被 JavaScript 讀取,能夠防止 XSS 攻擊

Cookie 字段只包含 Cookie 屬性。該屬性在請求中包含從服務器接收到的 Cookie,接收到多個 Cookie 時,一樣能夠以多個 Cookie 形式發送。

值得注意的時,爲了避免會佔據太多磁盤空間,每一個域的 cookie 總數有限的,不一樣瀏覽器之間各有不一樣。此外,對於 cookie 的尺寸也有限制。

另外,避免在 cookie 中存儲敏感信息。

Web Storage

Web Storage 是 HTML5 的一部分,目的是克服由 cookie 帶來的一些限制。

  • 提供一種在 cookie 以外存儲會話數據的途徑
  • 提供一種存儲大量能夠跨會話存在的數據的機制

Web Storage 提供兩種用於存儲數據的對象,sessionStorage 對象和 localStorage 對象。

sessionStorage

sessionStorage 對象存儲特定於某個會話的數據,該數據只保持到瀏覽器關閉。存儲在 sessionStorage 中的數據能夠跨越頁面刷新而存在。

另外,sessionStorage 對象應該主要用於僅針對會話的小段數據的存儲。若是須要跨越會話存儲數據,那麼 localStorage 更合適。

localStorage

存儲在 localStorage 中的數據保留到經過 JavaScript 刪除或者是用戶清除瀏覽器緩存。同時,localStorage 支持同源策略。也就是說,要訪問同一個 localStorage 對象,頁面必須來自同一個域。

同理,和其餘客戶端存儲方案相似,Web Storage 也有大小限制,因瀏覽器而異。

IndexedDB

IndexedDB 是在瀏覽器中保存結構化數據的一種數據庫。

參考:

相關文章
相關標籤/搜索