瀏覽器快取機制

2021-09-20 00:26:15 字數 3783 閱讀 1201

瀏覽器快取機制介紹

對於瀏覽器快取,相信很多開發者對它是又愛又恨,一方面,它可以極大地提公升使用者體驗,另一方面,在開發中經常會由於瀏覽器快取而展示了「錯誤」的東西。那麼,瀏覽器快取究竟是什麼呢?它的內部機制又是怎樣的?接下來就讓我跟大家分享一下瀏覽器快取機制。

簡單來說,瀏覽器快取就是把乙個已經請求過的 web 資源拷貝乙份儲存在瀏覽器中,當下次請求相同的資源時,瀏覽器會根據快取機制決定直接使用副本響應訪問請求還是再次向伺服器傳送請求。

如下圖所示是我在第二次開啟某個網頁時的資源請求圖,可以看出裡面大部分資源是從瀏覽器直接讀取了快取。

那麼瀏覽器快取究竟有什麼作用呢?在這裡我將瀏覽器快取的作用簡單地歸結為以下幾點。

加快頁面開啟速度

降低伺服器壓力

減少網路損耗

所以瀏覽器快取雖然有時對我們開發者來說並不那麼「友好」,但其對提公升使用者體驗卻有很大的幫助,接下來就讓我們來學習瀏覽器快取機制吧。

瀏覽器快取有 html meta 標籤控制與 http 頭資訊控制兩種。

html meta 標籤控制

html meta 標籤控制是指在 html 頁面中加入如下標籤

上述**的作用是告訴瀏覽器當前頁面不被快取,所以每當需要請求該頁面時都需要去伺服器獲取。

但由於僅有部分瀏覽器支援該標籤,並且所有的快取**伺服器均不支援,所以並未被廣泛使用。

http 頭資訊控制

瀏覽器每次在向伺服器發起 http 請求獲得請求結果(包含 http 頭資訊各種字段)後,會根據響應報文中 http 頭的快取標識字段(後面我們會知道這個字段就是 expires 和 cache-control),來決定是否將請求結果存入瀏覽器快取中。

瀏覽器每次在向伺服器發起 http 請求時,都會查詢瀏覽器快取中是否存在其相應的請求結果,然後根據快取標識欄位來決定其是直接使用之前快取的副本還是再次向伺服器發出 http 請求。

對於每次瀏覽器第一次 http 請求來說,瀏覽器快取中並不存在其請求資源相應的副本,這時瀏覽器便會直接向伺服器發出 http 請求來獲得相應的請求結果,並根據快取標識字段,來決定是否將請求結果作為副本存入瀏覽器快取中。

http 保持已快取資料與伺服器資料之間充分一致的機制稱為文件過期和伺服器再驗證。而從瀏覽器快取分類來看,也有將其分為強制快取和協商快取。

下面我就文件過期和伺服器再驗證的機制做詳細的介紹,下面表述的過程都是指瀏覽器快取中已經存在其相應資源副本的情況。

文件過期

當瀏覽器發起 http 請求時,會根據瀏覽器快取中的快取標識欄位來驗證文件(資源副本)是否過期。

上述說的快取標識字段便是 expires 和 cache-control。

expires 是伺服器端在響應請求時用來規定資源的失效時間。

cache-control 是伺服器端在響應請求時用來規定資源是否需要被瀏覽器快取以及快取的有效時間等。

cache-control 主要取值如下:

public:所有內容都將被快取(客戶端和**伺服器都可快取)

private:內容只快取到私有快取中(僅客戶端可以快取,**伺服器不可快取)

no-store:所有內容都不會被快取或 internet 臨時檔案中

must-revalidation/proxy-revalidation:如果快取的內容失效,請求必須傳送到伺服器/**以進行重新驗證

max-age=***:快取的內容將在 *** 秒後失效

這裡需要注意的是,no-cache 的作用是指跳過文件過期的驗證而直接進行伺服器再驗證,而 no-store 是指資源禁止被快取。

expires 是 http 1.0 的字段,而 cache-control 是 http 1.1 的字段,當 expires 與 cache-control 同時存在時,cache-control 的優先順序要高於 expires。

在瀏覽器快取中根據 expires 和 cache-control 的值來驗證文件(資源副本)是否過期的過程,稱為 http 的文件過期驗證機制。若是文件沒有過期,則瀏覽器會直接使用快取中的文件作為返回結果,若是文件已經過期了,則需要進行伺服器再驗證。

伺服器再驗證

在瀏覽器快取中,還儲存了其它關於資源副本的描述字段,這些欄位都是伺服器返回資訊頭帶過來的,如 last-modified 和 etag。

last-modified 是伺服器端在響應請求時用來說明資源的最後修改時間。與之對應的是 if-modified-since 字段,在伺服器再驗證過程中,瀏覽器傳送的 http 請求的請求頭中會帶上 if-modified-since 字段,值為該資源 last-modified 屬性的值。

當伺服器端接收到帶有 if-modified-since 屬性的請求時,則會將 if-modified-since 屬性的值與被請求資源的最後修改時間做對比。如果相同,說明資源沒有新的修改,則響應 http 304,瀏覽器會繼續使用原先儲存的該資源的副本;如果最後修改時間比較新,則說明資源被修改過,則響應 http 200,並且返回最新的資源。

etag 是伺服器端在響應請求時用來說明資源在伺服器端的唯一標識。與之對應的是 if-none-match 字段,在伺服器再驗證過程中,瀏覽器傳送的 http 請求的請求頭中會帶上 if-none-match欄位,值為該資源 etag 屬性的值。

當伺服器端接收到帶有 if-none-match 屬性的請求時,則會將 if-none-match 屬性的值與被請求資源的唯一標識做對比。如果相同,說明資源沒有新的修改,則響應 http 304,瀏覽器會繼續使用原先儲存的該資源的副本;如果不同,則說明資源被修改過,則響應 http 200,並且返回最新的資源。

那麼當 last-modified / if-modified-since 和 etag / if-none-match 同時存在是什麼情況呢?

事實上,當兩者同時存在時,etag / if-none-match 的優先順序要高於 last-modified / if-modified-since,http 1.1 中 etag 的出現主要是為了解決幾個 last-modified 比較難解決的問題:

last-modified 標註的最後修改只能精確到秒級,如果某些檔案在1秒鐘以內被修改多次的話,它將不能準確標註檔案的修改時間;

如果某些檔案會被定期生成,但有時內容並沒有任何變化,但 last-modified 卻改變了,導致檔案沒法使用快取;

有可能存在伺服器沒有準確獲取檔案修改時間,或者與**伺服器時間不一致等情形;

下面用一張流程圖來完整說明當瀏覽器發起 http 請求時快取機制的過程:

瀏覽器快取機制

最後,雖然說瀏覽器快取對使用者體驗有極大的好處,但是作為開發者,我們在開發的時候則需要禁止這「討厭」瀏覽器快取,我的方法是開啟瀏覽器的開發者工具,在 network 中有個 disable cache ,鉤上就可以了,鉤上後瀏覽器會忽略掉文件過期驗證和伺服器再驗證的過程,直接向伺服器請求最新的資源。

谷歌開發者工具禁用瀏覽器快取

瀏覽器快取機制

最近在準備優化日誌請求時遇到了一些令人疑惑的問題,比如為什麼響應頭里出現了兩個 cache control 為什麼明明設定了 no cache 卻還是發請求,為什麼多次訪問時有時請求裡帶了 etag,有時又沒有帶?等等。後來查了一些資料以及同事親自驗證,總算對這些問題有了個清晰的理解,現在整理出來以...

瀏覽器快取機制

當我們瀏覽乙個頁面發現有異常時,通常考慮的就是書不是瀏覽器做了快取呢,按ctrl f5重新請求一次就能請求到沒有快取的頁面,這個是為什麼呢。首先,ctrl f5組合鍵重新整理頁面,那麼瀏覽器會直接向目標url傳送請求,而不再使用瀏覽器快取的資料。其次,當請求到達伺服器端依然有可能出現使用伺服器端的資...

瀏覽器快取機制

瀏覽器快取機制 瀏覽器快取機制,其實主要就是 協議定義的快取機制 如 expires cache control 等 但是也有非 協議定義的快取機制,如使用 html meta 標籤,web 開發者可以在 html 頁面的節點中加入 標籤,如下 上述 的作用是告訴瀏覽器當前頁面不被快取,每次訪問都需...