Web 緩存有不少種,好比數據庫緩存、代理服務器緩存、CDN 緩存,以及瀏覽器緩存。html
瀏覽器緩存指的是將緩存文件保存在客戶端,通常是經過 HTTP 進行緩存。算法
HTTP/1.1 標準中固定了 HTTP 緩存的兩種方式: expiration 機制 和 validation 機制。前者是經過減小服務器和瀏覽器的循環次數,後者經過只響應頭部信息較少網絡帶寬。(有些參考資料,將前者稱爲強緩存,後者稱爲協商緩存)chrome
強緩存優先級高於協商緩存,也就是說,當執行強緩存的規則,緩存生效,則再也不執行協商緩存。數據庫
expiration 機制經過 Expires
和 Cache-Control
兩個字段來標明失效規則。瀏覽器
Expires緩存
Expires 的值爲服務器返回的到期時間,即下一次請求時,請求時間小於服務器返回的到期時間,直接使用緩存數據。可是因爲客戶端和服務器可能有時間差,會致使較大的緩存命中偏差,因此 HTTP/1.1 使用了 Cache-Control
替代。安全
Cache-Control服務器
Cache-Control 是很是重要的規則。取值以下:cookie
注意,Cache-Control 是一個通用的首部字段。因此,取值對客戶端和服務器端含義會有所不一樣。網絡
應用 HTTP/1.1 版本的緩存服務器同時存在 Expires 首部字段的狀況時,會優先處理 max-age 指令,而忽略 Expires 首部字段。
強緩存請求數據流程以下: 客戶端向緩存服務器(緩存數據庫)請求數據,若是有緩存數據且未失效,則返回數據。若是沒有緩存數據或緩存數據失效,則向服務器請求數據,服務器返回數據和緩存規則,客戶端收到並將數據和緩存規則存入緩存。
協商緩存的方式是客戶端發送請求驗證緩存標識所對應的數據是否失效,若是服務器判斷數據有效,則返回一個 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 比較難以解決的問題。好比:
因此,Etag 的優先級高於 Last-Modified 也是應該的。可是,性能上,Etag 要遜於 Last-Modified,由於 Last-Modified 指記錄修改的時間值,而 Etag 的值須要算法計算一個 hash 值。
對於一下操做,如地址欄回車、頁面連接跳轉、新開窗口、前進和回退,兩種機制( expires/validation )都是有效的。
F5 刷新操做,Expires/Cache-Control 是無效的,Last-Modified/Etag 是有效的,也就是說強制協商緩存。
Ctrl + F5 強制刷新,二者都是無效的。
抓包工具: Fiddler
查看 chrome 緩存
chrome://view-http-cache/
參考: 完全弄懂HTTP緩存機制及原理
應用緩存(application cache),簡稱 appcache,是專門爲開發離線 Web 應用設計的。它是從瀏覽器的緩存中分出來的一塊緩存區,使用一個 manifest
文件,列出要下載和緩存的資源。
第二步, 在須要離線使用的頁面中添加 manifest 屬性,用於指定緩存清單文件的路徑。好比:
<html manifest="/offline.manifest">
複製代碼
隨着 Web 應用的出現,也產生了可以直接在客戶端上存儲用戶信息能力的要求。
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 字段的屬性
Cookie 字段只包含 Cookie
屬性。該屬性在請求中包含從服務器接收到的 Cookie,接收到多個 Cookie 時,一樣能夠以多個 Cookie 形式發送。
值得注意的時,爲了避免會佔據太多磁盤空間,每一個域的 cookie 總數有限的,不一樣瀏覽器之間各有不一樣。此外,對於 cookie 的尺寸也有限制。
另外,避免在 cookie 中存儲敏感信息。
Web Storage 是 HTML5 的一部分,目的是克服由 cookie 帶來的一些限制。
Web Storage 提供兩種用於存儲數據的對象,sessionStorage
對象和 localStorage
對象。
sessionStorage 對象存儲特定於某個會話的數據,該數據只保持到瀏覽器關閉。存儲在 sessionStorage 中的數據能夠跨越頁面刷新而存在。
另外,sessionStorage 對象應該主要用於僅針對會話的小段數據的存儲。若是須要跨越會話存儲數據,那麼 localStorage 更合適。
存儲在 localStorage 中的數據保留到經過 JavaScript 刪除或者是用戶清除瀏覽器緩存。同時,localStorage 支持同源策略。也就是說,要訪問同一個 localStorage 對象,頁面必須來自同一個域。
同理,和其餘客戶端存儲方案相似,Web Storage 也有大小限制,因瀏覽器而異。
IndexedDB 是在瀏覽器中保存結構化數據的一種數據庫。
參考: