當前位置:首頁 » 硬碟大全 » 什麼情況下觸發強緩存
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

什麼情況下觸發強緩存

發布時間: 2022-12-07 18:43:27

① 瀏覽器緩存機制

有dns的地方,就有緩存。瀏覽器、操作系統、Local DNS、根域名伺服器,它們都會對DNS結果做一定程度的緩存。

DNS查詢過程如下:

首先搜索瀏覽器自身的DNS緩存,如果存在,則域名解析到此完成。
如果瀏覽器自身的緩存裡面沒有找到對應的條目,那麼會嘗試讀取操作系統的hosts文件看是否存在對應的映射關系,如果存在,則域名解析到此完成。
如果本地hosts文件不存在映射關系,則查找本地DNS伺服器(ISP伺服器,或者自己手動設置的DNS伺服器),如果存在,域名到此解析完成。
如果本地DNS伺服器還沒找到的話,它就會向根伺服器發出請求,進行遞歸查詢。

瀏覽器本地緩存失效後,瀏覽器會向CDN邊緣節點發起請求。類似瀏覽器緩存,CDN邊緣節點也存在著一套緩存機制。CDN邊緣節點緩存策略因服務商不同而不同,但一般都會遵循http標准協議,通過http響應頭中的
Cache-control: max-age 的欄位來設置CDN邊緣節點數據緩存時間。

當瀏覽器向CDN節點請求數據時,CDN節點會判斷緩存數據是否過期,若緩存數據並沒有過期,則直接將緩存數據返回給客戶端;否則,CDN節點就會向伺服器發出回源請求,從伺服器拉取最新數據,更新本地緩存,並將最新數據返回給客戶端。 CDN服務商一般會提供基於文件後綴、目錄多個維度來指定CDN緩存時間,為用戶提供更精細化的緩存管理。

CDN 優勢
CDN節點解決了跨運營商和跨地域訪問的問題,訪問延時大大降低。
大部分請求在CDN邊緣節點完成,CDN起到了分流作用,減輕了源伺服器的負載。

http請求報文(request)
請求行
請求方法  空格  URL 空格  協議版本 回車符 換行符
請求頭(通用信息頭、請求頭、實體頭)
頭部欄位名 冒號  值  回車鍵 換行符
...
頭部欄位名 冒號  值  回車鍵 換行符
空行
回車符   換行符
實體主體(只有post請求有)
主體

http響應報文(response)
狀態行
協議版本  空格  狀態碼 空格  狀態碼描述 回車符 換行符
響應頭部
頭部欄位名 冒號  值   回車符 換行符
...
頭部欄位名 冒號  值   回車符 換行符
空行
回車符   換行符
響應正文
正文

瀏覽器初次向伺服器發起請求後拿到請求結果,會根據響應報文中HTTP頭的緩存標識,決定是否緩存返回的結果,是則將請求結果和緩存標識存入瀏覽器緩存中

瀏覽器每次發起請求,都會現在瀏覽器緩存中查找該請求的結果以及緩存標識
瀏覽器                瀏覽器緩存        伺服器

——————第一次發起http請求——————>

<——沒有該請求的緩存結果和緩存標識————

——————————————發起http請求——————————————>

<——————————返回該請求結果和緩存規則————————————

——將請求結果和緩存標識存入瀏覽器緩存——>

強制緩存就是向瀏覽器緩存查找結果,並根據該結果的緩存規則來決定是否使用該緩存結果的過程

強制緩存的情況分為三種:
1、不存在該緩存結果和緩存標識,強制緩存失效,直接向伺服器發起請求
2、存在該緩存結果和緩存標識,但結果已經失效,強制緩存失效,使用協商緩存
3、存在該緩存結果和緩存標識,且該結果沒有失效,強制緩存生效,直接返回該結果

控制強制緩存的欄位:Expires,Cache-Control

Expires 是 HTTP/1.0 控制緩存的欄位,值為伺服器返回該請求的結果緩存時間
即再次發送請求是,客戶端時間 小於 Expires的值,直接使用緩存結果

Cache-Control 是HTTP/1.1的規則,主要用於控制網頁緩存,主要取值為:
public:所有的內容都緩存(客戶端和代理伺服器都可以緩存)
private:所有內容只有客戶端可以緩存(默認值)
no-cache:客戶端緩存內容,但是是否使用緩存則需要經過協商緩存來驗證決定
no-store:即不使用強制緩存,也不使用協商緩存
max-age=xxx:緩存內容將在xxx秒後失效

Expires 是一個絕對值
Cache-Control 中 max-age 是相對值,解決了 Expires時期 服務端與客戶端 可能出現時間差的問題

註:Expires和Cache-Control同時存在時,只有Cache-Control生效

協商緩存就是強制緩存失效後,瀏覽器攜帶緩存標識向伺服器發起請求,由伺服器根據緩存標識決定是否使用緩存的過程

協商緩存的兩種情況:
1、協商緩存生效,返回304,繼續使用緩存
過程:
瀏覽器                 瀏覽器緩存     伺服器

————————發起http請求————————>

<——該請求的緩存結果失效,只返回緩存標識——

————————攜帶該資源的緩存標識,發起http請求————————>

<—————————————304,該資源無更新————————————

——————獲取該請求的緩存結果——————>

<——————返回該請求的緩存結果——————

2、協商緩存失敗,返回200和請求結果
過程:
瀏覽器                 瀏覽器緩存     伺服器

————————發起http請求————————>

<——該請求的緩存結果失效,只返回緩存標識——

————————攜帶該資源的緩存標識,發起http請求————————>

<————————200,資源已更新,重新返回請求和結果———————

——將該請求結果和緩存標識存入瀏覽器緩存中—>

協商緩存的標識也是在響應報文的HTTP頭中和請求結果一起返回給瀏覽器的

控制協商緩存的欄位:
(1) Last-Modified/If-Modified-Since:Last-Modified是伺服器響應請求是,返回該資源文件在伺服器最後被修改的時間;If-Modified-Since再次發起請求時,攜帶上次返回的Last-Modified的值,伺服器將該欄位值與該資源最後修改時間對比,決定是否用緩存
(2)Etag/If-None-Match:Etag伺服器響應請求時,返回當前資源文件的一個唯一標識,由伺服器生成之;If-None-Match是再次發起請求時,攜帶上次返回的唯一標識Etag的值,伺服器收到後,將該欄位值與該資源在伺服器上的Etag對比,一致 則返回304,否則返回200

註:Etag/If-None-Match優先順序高於Last-Modified/If-Modified-Since,同時存在時只有Etag/If-None-Match生效

瀏覽器緩存分為:內存緩存 和 硬碟緩存

內存緩存特性:
(1)快速讀取:內存緩存會將編譯解析後的文件,存入該進程的內存中,便於下次運行時快速讀取
(2)時效性:一旦關閉進程,進程內存清空

硬碟緩存特性:
永久性:直接寫入硬碟文件中
復雜、緩慢:讀取緩存對該緩存存放的硬碟文件進行I/O操作,重新解析

from memory cache:使用內存中的緩存

from disk cache:使用硬碟中的緩存

瀏覽器讀取順序:memory ——> disk

瀏覽器將js和圖片等文件解析執行後直接存入內存緩存中,F5刷新頁面時,from memory cache(使用內存中的緩存)
css文件存入硬碟中,F5刷新頁面時,from disk cache(使用硬碟中的緩存)

參考文章
https://segmentfault.com/a/1190000017962411
https://www.cnblogs.com/chengxs/p/10396066.html

② 協商緩存和強緩存的區別

協商緩存和強緩存的區別
(1)強緩存
使用強緩存策略時,如果緩存資源有效,則直接使用緩存資源,不必再向伺服器發起請求。
強緩存策略可以通過兩種方式來設置,分別是 http 頭信息中的 Expires 屬性和 Cache-Control 屬性。
(1)伺服器通過在響應頭中添加 Expires 屬性,來指定資源的過期時間。在過期時間以內,該資源可以被緩存使用,不必再向伺服器發送請求。這個時間是一個絕對時間,它是伺服器的時間,因此可能存在這樣的問題,就是客戶端的時間和伺服器端的時間不一致,或者用戶可以對客戶端時間進行修改的情況,這樣就可能會影響緩存命中的結果。
(2)Expires 是 http1.0 中的方式,因為它的一些缺點,在 HTTP 1.1 中提出了一個新的頭部屬性就是 Cache-Control 屬性,它提供了對資源的緩存的更精確的控制。它有很多不同的值,
Cache-Control可設置的欄位:

public:設置了該欄位值的資源表示可以被任何對象(包括:發送請求的客戶端、代理伺服器等等)緩存。這個欄位值不常用,一般還是使用max-age=來精確控制;
private:設置了該欄位值的資源只能被用戶瀏覽器緩存,不允許任何代理伺服器緩存。在實際開發當中,對於一些含有用戶信息的HTML,通常都要設置這個欄位值,避免代理伺服器(CDN)緩存;
no-cache:設置了該欄位需要先和服務端確認返回的資源是否發生了變化,如果資源未發生變化,則直接使用緩存好的資源;
no-store:設置了該欄位表示禁止任何緩存,每次都會向服務端發起新的請求,拉取最新的資源;
max-age=:設置緩存的最大有效期,單位為秒;
s-maxage=:優先順序高於max-age=,僅適用於共享緩存(CDN),優先順序高於max-age或者Expires頭;
max-stale[=]:設置了該欄位表明客戶端願意接收已經過期的資源,但是不能超過給定的時間限制。

一般來說只需要設置其中一種方式就可以實現強緩存策略,當兩種方式一起使用時,Cache-Control 的優先順序要高於 Expires。
no-cache和no-store很容易混淆:

no-cache 是指先要和伺服器確認是否有資源更新,在進行判斷。也就是說沒有強緩存,但是會有協商緩存;
no-store 是指不使用任何緩存,每次請求都直接從伺服器獲取資源。

(2)協商緩存
如果命中強制緩存,我們無需發起新的請求,直接使用緩存內容,如果沒有命中強制緩存,如果設置了協商緩存,這個時候協商緩存就會發揮作用了。
上面已經說到了,命中協商緩存的條件有兩個:

max-age=xxx 過期了
值為no-store

使用協商緩存策略時,會先向伺服器發送一個請求,如果資源沒有發生修改,則返回一個 304 狀態,讓瀏覽器使用本地的緩存副本。如果資源發生了修改,則返回修改後的資源。
協商緩存也可以通過兩種方式來設置,分別是 http 頭信息中的Etag 和Last-Modified屬性。
(1)伺服器通過在響應頭中添加 Last-Modified 屬性來指出資源最後一次修改的時間,當瀏覽器下一次發起請求時,會在請求頭中添加一個 If-Modified-Since 的屬性,屬性值為上一次資源返回時的 Last-Modified 的值。當請求發送到伺服器後伺服器會通過這個屬性來和資源的最後一次的修改時間來進行比較,以此來判斷資源是否做了修改。如果資源沒有修改,那麼返回 304 狀態,讓客戶端使用本地的緩存。如果資源已經被修改了,則返回修改後的資源。使用這種方法有一個缺點,就是 Last-Modified 標注的最後修改時間只能精確到秒級,如果某些文件在1秒鍾以內,被修改多次的話,那麼文件已將改變了但是 Last-Modified 卻沒有改變,這樣會造成緩存命中的不準確。
(2)因為 Last-Modified 的這種可能發生的不準確性,http 中提供了另外一種方式,那就是 Etag 屬性。伺服器在返回資源的時候,在頭信息中添加了 Etag 屬性,這個屬性是資源生成的唯一標識符,當資源發生改變的時候,這個值也會發生改變。在下一次資源請求時,瀏覽器會在請求頭中添加一個 If-None-Match 屬性,這個屬性的值就是上次返回的資源的 Etag 的值。服務接收到請求後會根據這個值來和資源當前的 Etag 的值來進行比較,以此來判斷資源是否發生改變,是否需要返回資源。通過這種方式,比 Last-Modified 的方式更加精確。
當 Last-Modified 和 Etag 屬性同時出現的時候,Etag 的優先順序更高。使用協商緩存的時候,伺服器需要考慮負載平衡的問題,因此多個伺服器上資源的 Last-Modified 應該保持一致,因為每個伺服器上 Etag 的值都不一樣,因此在考慮負載平衡時,最好不要設置 Etag 屬性。
總結:
強緩存策略和協商緩存策略在緩存命中時都會直接使用本地的緩存副本,區別只在於協商緩存會向伺服器發送一次請求。它們緩存不命中時,都會向伺服器發送請求來獲取資源。在實際的緩存機制中,強緩存策略和協商緩存策略是一起合作使用的。瀏覽器首先會根據請求的信息判斷,強緩存是否命中,如果命中則直接使用資源。如果不命中則根據頭信息向伺服器發起請求,使用協商緩存,如果協商緩存命中的話,則伺服器不返回資源,瀏覽器直接使用本地資源的副本,如果協商緩存不命中,則瀏覽器返回最新的資源給瀏覽器。

前端瀏覽器緩存機制

在前端開發中,性能是一個永恆的話題,沒有最好,只有更好。判斷一個網站性能好壞,一個直入眼觀的即是網頁的反應速度,有一個方式就是使用緩存,一個優秀的緩存策略可以縮短網頁請求的時間,減少延遲,並且網頁可以重復利用,還可以減少帶寬,降低網路負荷。

1: 為什麼需要緩存?

a:緩存可以減少用戶等待時間,提升用戶體驗

b:減少網路帶寬消耗

c:降低伺服器壓力

Note:緩存使用不當,也會造成『臟數據』問題

2:常見的緩存類型

強緩存 -

Expires伺服器端設置,表示該資源的過期時間,會有弊端,客戶端時間和伺服器時間不一致的問題。

Cache-Control:max-age表示緩存資源的最大生命周期,單位是秒

所以Expires 結合 Cache-Control 一起使用,大型網站中一般比較適用

協商緩存-

Last-Modified:值為資源的最後更新時間,隨伺服器response返回

If-Modified-Since:通過比較兩個時間來判斷資源在兩次請求期間是否有過修改,如果沒有,則命中協商緩存

Etag:表示資源內容的唯一標識,即資源的消息摘要

If-None-Match:伺服器通過比較請求頭中的If-None-Match與當前資源的Etag是否一致來判斷資源是否在兩次請求期間有過修改

3:緩存流程圖示:

a:瀏覽器會先檢測強緩存類型(Cache-Control 或者 Expires)是否有效;命中直接瀏覽器本地獲取緩存資源

b:未命中。伺服器會根據請求頭Request Header驗證這個資源是否命中協商緩存,稱之為HTTP二次驗證,命中,伺服器返回請求,但返回資源,而是告訴客戶端直接中直接從瀏覽器緩存中獲取

Note:

1.強緩存不會發生請求,協商緩存存在伺服器請求

2.當協商緩存也未命中時,則伺服器會將資源發送到客戶端

3.F5刷新頁面,會跳過強緩存

4.Ctrl+F5刷新頁面,跳過強緩存和協商緩存

5.不會緩存的情況

HTTPS POST請求 根據Cookie獲取認證信息 Request Header Cache-Control:no-cache, max-age=0

6.小故事大道理

上文對整個概念做了闡述,還是不夠形象,我們來通過幾個小故事生動理解一下:

故事一:Last-Modified

瀏覽器:Hi,我需要 jartto.min.js 這個文件,如果是在 Last-Modified: Fri Feb 15 2019 19:57:31 GMT 之後修改過的,請發給我。

伺服器:(檢查文件的修改時間)

伺服器:Oh,這個文件在那個時間之後沒有被修改過,你已經有最新的版本了。

瀏覽器:太好了,那我就顯示給用戶了。

故事二:ETag

瀏覽器:Hi,我需要 jartto.css 這個文件,有沒有不匹配 3c61f-1c1-2aecb436 這個串的

伺服器:(檢查 ETag…)

伺服器:Hey,我這里的版本也是 3c61f-1c1-2aecb436,你已經是最新的版本了

瀏覽器:好,那就可以使用本地緩存了

④ 前端緩存的理解 或者 前端數據持久化的理解(強制緩存、協商緩存)

緩存可以說是性能優化中簡單高效的一種優化方式了。一個優秀的緩存策略可以縮短網頁請求資源的距離,減少延遲,並且由於 緩存文件可以重復利用 ,還可以減少帶寬,降低網路負荷。

        對於一個數據請求來說,可以分為發起 網路請求、後端處理、瀏覽器響應 三個步驟。瀏覽器緩存可以幫助我們在第一和第三步驟中優化性能。比如說直接使用緩存而不發起請求,或者發起了請求但後端存儲的數據和前端一致,那麼就沒有必要再將數據回傳回來,這樣就減少了響應數據。

①不存在該緩存結果和緩存標識,強制緩存失效,則直接向伺服器發起請求

②存在該緩存結果和緩存標識,但該結果已失效,強制緩存失效,則使用協商緩存

③存在該緩存結果和緩存標識,且該結果尚未失效,強制緩存生效,直接返回該結果

控制強制緩存的欄位分別是Expires和Cache-Control,其中Cache-Control優先順序比Expires高。

Cache-Control、Expires都是緩存到期時間,Cache-Control是相對值,Expires是絕對值,即再次發送請求時,如果時間沒到期,強制緩存生效。

註:在無法確定客戶端的時間是否與服務端的時間同步的情況下,Cache-Control相比於expires是更好的選擇,所以同時存在時,只有Cache-Control生效。

①協商緩存生效,返回304

②協商緩存失效,返回200和請求結果

這里我們以博客的請求為例,狀態碼為灰色的請求則代表使用了強制緩存,請求對應的Size值則代表該緩存存放的位置,分別為from memory cache 和 from disk cache。那麼from memory cache 和 from disk cache又分別代表的是什麼呢?什麼時候會使用from disk cache,什麼時候會使用from memory cache呢?

from memory cache代表使用 內存中的緩存 ,from disk cache則代表使用的是 硬碟中的緩存 ,

⑤ Okhttp解析(五)緩存的處理

大家好,之前我們講解了Okhttp網路數據請求相關的內容,這一節我們講講數據緩存的處理。本節按以下內容講解Okhttp緩存相關的內容。

緩存的使用場景很多,通過它可以將數據通過一定的規則存儲起來,再次請求數據的時候就可以快速從緩存中讀取了,緩存有以下優勢。

HTTP本身提供了一套緩存相關的機制。這套機制定義了相關的欄位和規則,用來客戶端和服務端進行緩存相關的協商,如響應的數據是否需要緩存,緩存有效期,緩存是否有效,伺服器端給出指示,而客戶端則根據服務端的指示做具體的緩存更新和讀取緩存工作。http緩存可以分為兩類:

強制緩存,在緩存數據未失效的情況下,可以直接使用緩存數據,有兩個欄位Expires和Cache-Control用於標明失效規則。

表示過期時間,由服務端返回。那麼下次請求數據時,判斷這個Expires過期時間是否已經過了,如果還沒有到過期時間,則使用緩存,如果過了過期時間,則重新請求伺服器的數據。Expires格式如下:

不過因為伺服器和客戶端的時間並不是同步的,用一個絕對時間作為過期的標記並不是很明智,所以HTTP1.1之後更多的是Cache-Control,它的控制更加靈活。

表示緩存的控制,有服務端返回。它有以下幾個取值:

默認情況下是private,也就是不能共享的。Cache-Control格式如下:

對比緩存,表示需要和服務端進行相關信息的對比,由伺服器決定是使用緩存還是最新內容,如果伺服器判定使用緩存,返回響應嗎304,判定使用最新內容,則返回響應碼200和最新數據。對比緩存的判定欄位有兩組:

ETag表示資源的一種標識信息,用於標識某個資源,由服務端返回,優先順序更高。格式如下:

然後客戶端再次請求時,加入欄位If-None-Match,格式如下:

服務端收到請求的該欄位時(之前的Etag值),和資源的唯一標識進行對比,如果相同,說明沒有改動,則返回狀態碼304,如果不同,說明資源被改過了,則返回狀態碼200和整個內容數據。

Last-Modified表示資源的最近修改時間,由服務端返回,優先順序更低。格式如下:

Last-Modified
由伺服器返回,表示響應的數據最近修改的時間。


If-Modified-Since
由客戶端請求,表示詢問伺服器這個時間是不是上次修改的時間。如果服務端該資源的修改時間小於等於If-Modified-Since指定的時間,說明資源沒有改動,返回響應狀態碼304,可以使用緩存。如果服務端該資源的修改時間大於If-Modified-Since指定的時間,說明資源又有改動了,則返回響應狀態碼200和最新數據給客戶端,客戶端使用響應返回的最新數據。

Last-Modified欄位的值(服務端返回的資源上次修改時間),常常被用於客戶端下次請求時的If-Modified-Since欄位中。

HTTP的緩存規則是優先考慮強制緩存,然後考慮對比緩存。

Okhttp緩存相關的類有如下:

要開啟使用Okhttp的緩存其實很簡單,只需要給OkHttpClient對象設置一個Cache對象即可,創建一個Cache時指定緩存保存的目錄和緩存最大的大小即可。

那麼下面我們來看看Okhttp緩存執行的大概流程

Okhttp的緩存流程分為讀取緩存和存儲緩存兩個過程,我們分別分析。

讀取使用緩存的流程從HttpEngine的sendRequest發送請求開始。

接下來我們分析

從Cache的get方法開始。它按以下步驟進行。

如果存在緩存的話,在指定的緩存目錄中,會有兩個文件「****.0」和「****.1」,分別存儲某個請求緩存的響應頭和響應體信息。(「****」是url的md5加密值)對應的ENTRY_METADATA響應頭和ENTRY_BODY響應體。緩存的讀取其實是由DiskLruCache來讀取的,DiskLruCache是支持Lru(最近最少訪問)規則的用於磁碟存儲的類,對應LruCache內存存儲。它在存儲的內容超過指定值之後,就會根據最近最少訪問的規則,把最近最少訪問的數據移除,以達到總大小不超過限制的目的。

接下來我們分析CacheStrategy緩存策略是怎麼判定的。

直接看CacheStrategy的get方法。緩存策略是由請求和緩存響應共同決定的。

接來下我們看看CacheControl類里有些什麼。

可以發現,它就是用於描述響應的緩存控制信息。

然後我們再看看Okhttp存儲緩存是怎麼進行的。

存儲緩存的流程從HttpEngine的readResponse發送請求開始的。

可以看到這里先通過maybeCache寫入了響應頭信息,再通過cacheWritingResponse寫入了響應體信息。我們再進去看Cache的put方法實現。

我們繼續看Cache的writeTo方法,可以看到是寫入一些響應頭信息。

到這里Okhttp緩存的讀取和存儲流程我們就清楚了。可以說,緩存的使用策略基本都是按照HTTP的緩存定義來實現的,所以對HTTP緩存相關欄位的理解是很重要的。然後關於DiskLruCache是如何管理緩存文件的,這個其實也很好理解,首先的原則就是按照LRU這種最近最少使用刪除的原則,當總的大小超過限定大小後,刪除最近最少使用的緩存文件,它的LRU演算法是使用LinkedHashMap進行維護的,這樣來保證,保留的緩存文件都是更常使用的。具體實現大家可以分析DiskLruCache和LinkedHashMap的實現原理。