強快取和協商快取

2021-10-02 01:16:55 字數 2693 閱讀 5265

對於一次已經有快取存在的請求來說(即之前已經發過針對這個資源的請求,在本地已經有快取),如果發起請求,那麼

首先會去找到快取資源的響應頭中的expires(過期時間)和cache-control(控制快取的失效性)來判斷當前是否直接使用快取,如果當前時間還在expires之前,即快取仍未失效的情況下,我們就直接使用快取,這就是強快取。

如果快取已經失效,那麼此時我們需要向後台傳送請求,此時傳送的請求並非直接就會從伺服器獲取資源內容,而是在請求頭中,加入if-modified-since(在其值後,資源是否更新)或者 if-none-match(比較etag的值,相同則返回304,客戶端從快取中讀取內容,否則返回200資源),這兩個字段對應的值分別為第一次請求時返回的last-modified(上一次修改的時間)和etag(資源的唯一標識),如果判斷後資源尚未更新,就繼續訪問快取資源,不會返回新的資源內容,如果已經更新,則會返回資源的實際內容,並更新header中相關的快取字段,這就是協商快取。

強快取是根據返回頭中的expires或者cache-control兩個欄位來控制的,都是表示資源的快取有效時間。

expires是 http 1.0 的規範,值是乙個gmt 格式的時間點字串,比如 expires:mon,18 oct 2066 23:59:59 gmt 。這個時間點代表資源失效的時間,如果當前的時間戳在這個時間之前,則判定命中快取。有乙個缺點是,失效時間是乙個絕對時間,如果伺服器時間與客戶端時間偏差較大時,就會導致快取混亂。而伺服器的時間跟使用者的實際時間是不一樣是很正常的,所以 expires 在實際使用中會帶來一些麻煩。

cache-control這個欄位是 http 1.1 的規範,一般常用該字段的 max-age 值來進行判斷,它是乙個相對時間,比如

.cache-control:max-age=3600 代表資源的有效期是 3600 秒。並且返回頭中的 date 表示訊息傳送的時間,表示當前資源在 date ~ date +3600s 這段時間裡都是有效的。不過我在實際使用中常常遇到設定了 max-age 之後,在 max-age 時間內重新訪問資源卻會返回 304 not modified ,這是由於伺服器的時間與本地的時間不同造成的。當然 cache-control 還有其他幾個值可以設定, 不過相對來說都很少用了:

no-cache 不使用本地快取。需要使用協商快取。

no-store直接禁止瀏覽器快取資料,每次請求資源都會向伺服器要完整的資源, 類似於 network 中的 disabled cache。

public 可以被所有使用者快取,包括終端使用者和 cdn 等中介軟體**伺服器。

private 只能被終端使用者的瀏覽器快取。

如果 cache-control與 expires 同時存在的話, cache-control 的優先順序高於 expires。

簡單來說,協商快取會通過在請求中新增if-modified-since欄位和if-none-match欄位來向伺服器確認當前資源是否繼續使用快取。

協商快取是由伺服器來確定快取資源是否可用。 主要涉及到兩對屬性字段,都是成對出現的,即第一次請求的響應頭帶上某個字, last-modified 或者 etag,則後續請求則會帶上對應的請求字段 if-modified-since或者 if-none-match,若響應頭沒有 last-modified 或者 etag 字段,則請求頭也不會有對應的字段。

last-modified/if-modified-since 二者的值都是gmt格式的時間字串, last-modified 標記最後檔案修改時間, 下一次請求時,請求頭中會帶上 if-modified-since 值就是 last-modified 告訴伺服器我本地快取的檔案最後修改的時間,在伺服器上根據檔案的最後修改時間判斷資源是否有變化, 如果檔案沒有變更則返回 304 not modified ,請求不會返回資源內容,瀏覽器直接使用本地快取。當伺服器返回 304 not modified 的響應時,response header 中不會再新增的 last-modified 去試圖更新本地快取的 last-modified, 因為既然資源沒有變化,那麼 last-modified 也就不會改變;如果資源有變化,就正常返回返回資源內容,新的 last-modified 會在 response header 返回,並在下次請求之前更新本地快取的 last-modified,下次請求時,if-modified-since會啟用更新後的 last-modified。

etag/if-none-match,值都是由伺服器為每乙個資源生成的唯一標識串,只要資源有變化就這個值就會改變。伺服器根據檔案本身算出乙個雜湊值並通過 etag欄位返回給瀏覽器,接收到 if-none-match 字段以後,伺服器通過比較兩者是否一致來判定檔案內容是否被改變。與 last-modified 不一樣的是,當伺服器返回 304 not modified 的響應時,由於在伺服器上etag 重新計算過,response header中還會把這個 etag 返回,即使這個 etag 跟之前的沒有變化。

對於強快取來說,會直接去檢視快取資源中的響應頭的字段值,以此來判斷快取的資源是否還能使用,在這個過程中,不需要向伺服器發起請求。

而對於協商快取來說,要判斷快取是否能使用,需要通過發起請求,帶著與快取相關的字段,到伺服器去做過期判斷後,才能通過相應的內容做出相應的操作。(是回去拿快取的資源,還是拿這次伺服器返回的資源)

所以說最終使用的是什麼快取,是由上一次請求得到的快取資源中的頭部來決定的,而這個資源是由伺服器發來的,實際上就是由伺服器來決定的。

強快取和協商快取

一 瀏覽器快取 1,第一次請求,無快取請求過程 流程如下所示 第二次請求,有快取請求的過程 流程如下圖所示 瀏覽器的快取分為二種,第一種的是強快取,另外一種是協商快取 2 強快取 定義 強快取在請求資源的時候,會從header裡面讀取是否是強快取,在有效的時間時間期內,從快取裡讀取不能從服務那裡讀取...

前端強快取和協商快取

快取是前端面試的乙個常見知識點,下面對於實際專案中如何進行快取的設定給出方案。瀏覽器快取是瀏覽器將使用者請求過的靜態資源儲存到電腦本地磁碟中,當再次訪問時,就可以直接從本地快取中載入而不需要去向伺服器請求了。但是快取也有缺點,如果服務端資源更新了,客戶端沒有強制重新整理的情況下,看到的內容還是舊的。...

Http強快取和協商快取

本文主要講解瀏覽器端的快取,快取的作用是不言而喻的,能夠極大的改善網頁效能,提高使用者體驗。快取這東西,第一次必須獲取到資源後,然後根據返回的資訊來告訴如何快取資源,可能採用的是強快取,也可能告訴客戶端瀏覽器是協商快取,這都需要根據響應的header內容來決定的。下面用兩幅圖來描述瀏覽器的快取是怎麼...