天天看點

一文讀懂浏覽器存儲與緩存機制

Cookie

Cookie 是 HTTP 協定的一種無狀态協定。當請求伺服器時,HTTP 請求都需要攜帶 Cookie,用來驗證使用者身份。Cookie 由服務端生成,存儲在用戶端,用來維持狀态。

通常 Cookie 由以下值構成:

Cookie 有一些限制,它可以設定有過期時間,但是如果沒有設定,則會和 session 一個級别,一旦關閉浏覽器就會消失。

Cookie 擁有以下優點:

可以控制過期時間,不會永久有效,有一定的安全保障。

可進行擴充,可跨域共享。

通過加密與安全傳輸技術 (SSL),可以減少 Cookie 被破解的可能性。

有較高的相容性。

缺點則如下:

有一定的數量與長度限制,每個 Cookie 長度不能超過 4KB ,否則超出部分會被截掉。

請求頭上的資料容易被攔截攻擊。

單個 Cookie 大小不超過 4KB,很多浏覽器都限制一個站點最多儲存 20 個 Cookie。

web Storage

H5 可以在本地存儲使用者的浏覽資料,以前用 Cookie,但是 web Storage 更快速、安全。可以存儲大量的資料,而不影響網站性能,以鍵/值對存在。

web Storage 分為兩種:sessionStorage 和 localStorage。

sessionStorage

sessionStorage 将資料存儲在 session 中,當浏覽器關閉就會消失。它具有以下特色:

主要被應用在下面這些場景中:

主要針對會話級的小資料的存儲。

存儲一些在目前頁面重新整理仍然需要存儲,但是關閉後不需要留下的資訊。

很适合單頁應用的使用,可以用來存儲登入态資訊等。

localStorage

localStorage 會把資料一直存在用戶端本地。其 API 提供了如下的方法進行操作:

setItem (key,value) —— 儲存資料,以鍵值對的方式存儲。

getItem (key) —— 讀取資料,傳入鍵值(key),獲得對應的值(value)。

removeItem (key) —— 删除某個資料,删除鍵值對。

clear () —— 删除所有資料。

key (index) —— 擷取某個索引的key。

下面是 localStora 的特性:

它通常都被運用在下列場景中:

持久性的儲存用戶端資料,隻能通過 JavaScript 删除或者使用者清除浏覽器緩存。

如果有一些稍大量的資料,例如編輯器的自動儲存等。

多頁面間通路共同資料。sessionStorage 隻能用于一個标簽頁,而localStorage可以在多個标簽頁之間共享。

浏覽器的緩存機制是将已通路過的資源進行緩存,這樣當用戶端下次通路時,就能直接通路已經緩存的資源,進而減少伺服器請求次數,讓頁面能夠更快地加載。

而判斷是否通路緩存則是依靠 HTTP 的各種 Header,比如下面的這幾種:

Expires:響應頭,表示該資源的過期時間。

Cache-Control:請求頭/響應頭,是緩存控制字段。

Etag (HTTP1.1):響應頭,是資源辨別,伺服器存儲。一旦資源被修改,Etag 就會随之發生變化。

lf-None-Match (HTTP1.1):請求頭,一般伺服器會将 If-None-Match 與被請求資源的最新 ETag 進行比對。

Last-Modified (HTTP1.0):響應頭,表示資源最後一次修改的時間。

If-Modified-Since (HTTP1.0):請求頭,資源最後一次修改時間(後面詳情)。

這些 Header 共同組成了 HTTP 的請求和響應,也支撐着浏覽器緩存,但是這種緩存方式是有缺陷的。

首先,如果資源更新的速度是秒以下機關,那麼這個緩存是不能被使用的。因為它的時間機關最低是秒。

其次,如果檔案是通過伺服器動态生成的,那麼該方法的更新時間永遠是生成的時間。哪怕檔案可能沒有變化,它也會自動更新,是以起不到緩存的作用。

強緩存

通常伺服器會通知浏覽器一個緩存時間,這個資訊在 Cache-Control 和 Expires 中,浏覽器通過這個判斷是緩存否過期。如果時間未過期。則直接從緩存中取。這就是所謂的“強緩存”。

Expires

在 HTTP1.0 中。使用 Expires 字段來表示緩存的到期時間,即有效時間+當時伺服器的時間。但是這種方式的缺陷是,使用者隻需要修改用戶端本地時間,讓用戶端和伺服器時間不一緻時,浏覽器就會判斷緩存失效,然後重新請求資源。

Cache-control

Cache-Control 是一個 HTTP 協定中關于緩存的響應頭,它可以由以下值組成:

max-age:用于設定緩存的最大周期。與 Expires 相反,它的時間是相對于請求的時間。

s-maxage:和 max-age 相同,僅用于共享緩存,如 CDN 緩存。

public:相應可以被任何對象緩存,即使是通常不可緩存的内容。

private:緩存隻能被單個使用者緩存,不能作為共享緩存(即代理伺服器不可緩存)。

no-cache:可以緩存在用戶端,但每次都必須去伺服器檢查新鮮度,來決定從伺服器擷取最新資源(200)還是讀取緩存(304),即協商緩存。

no-store:不允許在用戶端存儲,每次都要從伺服器請求新的資源。

協商緩存

如果未命中強緩存,即強緩存失效(可能是 Cache-Control 設定了 no-store 或 no-cache),則判斷協商緩存。

Last-Modified & If-Modified-Since(HTTP1.0)

當第一次請求資源後,伺服器會傳回改資源最後一次修改的時間。之後再次請求時,伺服器會對比 If-Modified-Since 和 Last-Modified 字段。如果兩者相同,則表示資源未修改,傳回 304 狀态碼。如果兩者不同,則表示資源已經修改了,是以傳回資料和 200 狀态碼(沒有發送請求)。

但是如果伺服器更新資源的時間機關為秒,而上面提到的方法是無法識别一秒内進行多次修改的情況的。同時如果資源更新的速度不到 1ms,也是無法生成新的最後修改時間的。為了避免這種情況,在 HTTP1.1 中出現了一組新的字段:Etag 和 If-None-Match。

Etag & If-None-Match (HTTP1.1)

Etag 是 HTTP1.1 的屬性。它由伺服器生成并傳回給用戶端,優先級高于 Last-Modified。

在 HTTP1.1 中,當浏覽器第一次發起 HTTP 請求時,伺服器回傳回一個 Etag。浏覽器第二次發起同一個請求時,用戶端會發送一個 If-None-Match,它的值就是 Etag。伺服器會比較浏覽器發送過來的 Etag 和伺服器的 Etag,如果相同就将 If-None-Match 的值設定為 false,并傳回304,表示使用浏覽器緩存。如果不同,伺服器就将 If-None-Match 的值設定為 true,傳回 200 和新的資料。

網頁加載速度的加快絕不僅僅是網速加快就能完成的,在我們流暢通路的背後,浏覽器存儲和緩存機制也功不可沒,希望本文能夠幫助大家增加對這個機制的了解。

參考資料:

深入了解浏覽器的緩存機制 https://www.jianshu.com/p/54cc04190252

一文讀懂前端緩存 https://juejin.cn/post/6844903747357769742?utm_source=gold_browser_extension

浏覽器的存儲與緩存機制 https://blog.csdn.net/wantingtr/article/details/100559520

上網時遇到的 404 是什麼意思

全站 HTTPS 就一定安全了嗎?