溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

HTTP緩存策略是什么

發(fā)布時間:2021-10-21 11:40:07 來源:億速云 閱讀:170 作者:iii 欄目:編程語言

這篇文章主要講解了“HTTP緩存策略是什么”,文中的講解內(nèi)容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“HTTP緩存策略是什么”吧!

我就跟朋友討論了一下HTTP的緩存策略:

朋友說:“HTTP里面控制緩存的頭(header)太多了,啥Cache-ControlETag,Last-Modified,一大堆,亂七八糟的,而且之間邏輯關系不強,要掌握基本靠背!”

我有點驚訝:“為什么要去背這個呢?所有的技術都是為了解決問題而存在的,不了解問題而去單純的學習技術,去,背,去,死記,確實很枯燥,而且效果不好。HTTP緩存策略只是為了解決客戶端和服務端信息不對稱的問題而存在的,客戶端為了加快速度會緩存部分資源,但是下次請求時,客戶端不知道這個資源有沒有更新,服務端也不知道客戶端緩存的是哪個版本,不知道該不該再返回資源,其實就是一個信息同步問題,HTTP緩存策略就是來解決這個問題的。如果我們跳出這種純粹的技術思維,我們會發(fā)現(xiàn)生活中這種信息同步問題也很常見。而我們解決這些問題的思路很多時候都是司空見慣了,如果從這個角度來說,這個問題就很好理解!”

于是我給他講了一個我小時候租光碟看奧特曼的故事。

租光碟看奧特曼

事情是這樣的,我小時候特別喜歡看動畫片,尤其是奧特曼,但是那時候沒有電腦啊,也沒有網(wǎng)絡。我只有一臺DVD播放機,于是我會經(jīng)常跑去租光碟的店租奧特曼。

ETag

某天,我看完了《艾斯奧特曼》第10集,我還想繼續(xù)看。于是我找到了光碟店的老板:“老板,第10集我看完了哦,你還有沒有新的???”老板說:“有有有,剛出了第11集,你拿去吧!”

上面這一個簡單的交流過程其實就包含了一個HTTP的緩存技術,那就是ETag!類比于網(wǎng)絡請求,我其實就是客戶端,光碟店就是服務端,我去租光碟就相當于發(fā)起一個請求。但是我去租光碟時,老板并不知道我看到哪集了,我們的信息是不同步的。所以我告訴了他一個標記(Tag),在這里這個標記就是第10集,老板拿到這個標記,跟他自己庫存的標記比較一下,發(fā)現(xiàn)他最新標記是第11集,于是知道有更新了,將第11集給了我。

Last-Modified & If-Modified-Since

再來,我《艾斯奧特曼》看完了,我開始看《泰羅奧特曼》了??墒抢习暹@次比較雞賊,《泰羅奧特曼》沒買正版的,是他自己翻錄的,他翻錄的時候自己也不知道是第幾集,但是他聰明的在光盤上寫上了翻錄日期。于是我正在看的這盤也沒啥封面,只光禿禿的寫了一個2000年12月1日。當我這盤看完了,我又去找老板了:“老板,你這個2000年12月1日的我已經(jīng)看完了,你還有沒有新的???”這里的2000年12月1日其實就是標記了我手上副本的更新日期,這也對應了HTTP的一個緩存技術,那就是Last-ModifiedIf-Modified-Since。你可以理解為,老板給日期還取了一個名字,叫Last-Modified,所以光碟上完整文字是Last-Modified:2000年12月1日,而我去問的時候就這么問:“Do you have any updates IF-Modified-Since 2000年12月1日?”。

Expires和Max-Age

繼續(xù),我《泰羅奧特曼》也看完了,開始看《雷歐奧特曼》了。這《雷歐奧特曼》跟前面兩個都不一樣,我去租的時候老板就說了:“你小子別天天跑來問了!《雷歐奧特曼》我每周去進一次貨,你每周一來拿就行!”這句話也對應了一個HTTP緩存技術,那就是ExpiresMax-Age。我知道了下周一之前,我手上都是最新的,到了下周一就過期(Expire)了。所以“我手上的是最新的”這個說法有個生命周期,他的年齡是有限的,他的年齡等于下周一更新時間減去當前時間,這就是他的最大年齡(Max-Age)。

Immutable

再來一個,我《雷歐奧特曼》也看完了,開始看《奈克斯特奧特曼》了。這《奈克斯特奧特曼》跟前面幾個都不一樣,我去租的時候老板說了:“小子,你這次運氣好,這《奈克斯特奧特曼》已經(jīng)出完了,你全部拿去吧,也不用天天跑來問了!”這句話對應的HTTP緩存技術是啥?當然是Immutable!Immutable就跟字面意思一樣,不可變的!就像《奈克斯特奧特曼》一樣,已經(jīng)出完了,不用再去問更新了。

言歸正傳

扯蛋到這里結(jié)束,咱們言歸正傳!之所以舉這么個例子,是為了說明HTTP緩存技術要解決的問題在生活中很常見,從這些常見的場景入手,理解起來更簡單。下面我們正兒八經(jīng)的來說說HTTP緩存技術:

兩種機制

從上面的幾個小例子可以看出,有時候為了知道是不是有更新,我必須去問老板,比如第一個例子里面:“老板,第10集我看完了哦,你還有沒有新的???”。這種為了知道有沒有更新,必須跟服務端溝通過才知道的,我們稱之為協(xié)商緩存。還有些場景,我不去問就知道有沒有更新,比如第三個例子,因為知道是周更的,當周一來之前,我都不會去問了,到了周一再去問,這種不用跟服務器協(xié)商直接用本地副本的叫做強制緩存。換成技術的話說就是,強制緩存不用發(fā)請求直接用本地緩存,協(xié)商緩存要發(fā)請求去問服務器有沒有更新。下面我們詳細來講下這兩種緩存:

協(xié)商緩存

前面第一個例子和第二個例子每次都需要向服務器端詢問,所以是協(xié)商緩存

ETag和If-None-Match

ETag是URL的Entity Tag,就是一個URL資源的標識符,類似于文件的md5,計算方式也類似,當服務器返回時,可以根據(jù)返回內(nèi)容計算一個hash值或者就是一個數(shù)字版本號,類似于我們的第10集,具體返回什么值要看服務器的計算策略。然后將它加到responseheader里面,可能長這樣:

ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"

客戶端拿到后會將這個ETag和返回值一起存下來,等下次請求時,使用配套的If-None-Match,將這個放到requestheader里面,可能長這樣:

If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"

然后服務端拿到請求里面的If-None-Match跟當前版本的ETag比較下:

  1. 如果是一樣的話,直接返回304,語義為Not Modified,不返回內(nèi)容(body),只返回header,告訴瀏覽器直接用緩存。

  2. 如果不一樣的話,返回200和最新的內(nèi)容

ETag配套的還有一個不太常用的request header ----If-Match,這個和前面If-None-Match的語義是相反的。前面If-None-Match的語義是如果不匹配就下載。而If-Match通常用于post或者put請求中,語義為如果匹配才提交,比如你在編輯一個商品,其他人也可能同時在編輯。當你提交編輯時,其他人可能已經(jīng)先于你提交了,這時候服務端的ETag就已經(jīng)變了,If-Match就不成立了,這時候服務端會給你返回412錯誤,也就是Precondition Failed,前提條件失敗。如果If-Match成立,就正常返回200。

Last-Modified & If-Modified-Since

Last-ModifiedIf-Modified-Since也是配套使用的,類似于ETagIf-None-Match的關系。只不過ETag放的是一個版本號或者hash值,Last-Modified放的是資源的最后修改時間。Last-Modified是放到responseheader里面的,可能長這樣:

Last-Modified: Wed, 21 Oct 2000 07:28:00 GMT

而客戶端瀏覽器在使用時,應該將配套的If-Modified-Since放到**requestheader里面**,長這樣:

If-Modified-Since: Wed, 21 Oct 2000 07:28:00 GMT

服務端拿到這個頭后,會跟當前版本的修改時間進行比較:

  1. 當前版本的修改時間比這個晚,也就是這個時間后又改過了,返回200和新的內(nèi)容

  2. 當前版本的修改時間和這個一樣,也就是沒有更新,返回304,不返回內(nèi)容,只返回頭,客戶端直接使用緩存

If-Modified-Since對應的還有If-Unmodified-Since,If-Modified-Since可以理解為有更新才下載,那If-Unmodified-Since就是沒有更新才下載。如果客戶端傳了If-Unmodified-Since,像這樣:

If-Unmodified-Since: Wed, 21 Oct 2000 07:28:00 GMT

服務端拿到這個頭后,也會跟當前版本的修改時間進行比較:

  1. 如果這個時間后沒有更新,服務器返回200,并返回內(nèi)容。

  2. 如果這個時間后有更新,其實就是這個if不成立,會返回錯誤代碼412,語義為Precondition Failed

ETag和Last-Modified優(yōu)先級

ETagLast-Modified都是協(xié)商緩存,都需要服務器進行計算和比較,那如果這兩個都存在,用哪個呢?答案是ETag,ETag的優(yōu)先級比Last-Modified。因為Last-Modified在設計上有個問題,那就是Last-Modified的精度只能到秒,如果一個資源頻繁修改,在同一秒進行多次修改,你從Last-Modified上是看不出來區(qū)別的。但是ETag每次修改都會生成新的,所以他比Last-Modified精度高,更準確。但是ETag也不是完全沒問題的,你的ETag如果設計為一個hash值,每次請求都要計算這個值,需要額外耗費服務器資源。具體使用哪一個,需要根據(jù)自己的項目情況來進行取舍。

強制緩存

上面扯蛋那里的第三個例子和第四個例子就是強制緩存,就是我知道在某個時間段完全不用去問服務端,直接去用緩存就行。這兩個例子里面提到的Expires是一個單獨的header,max-ageimmutable同屬于Cache-Control這個header。

Expires

Expires比較簡單,就是服務器responseheader帶上這個字段:

Expires: Wed, 21 Oct 2000 07:28:00 GMT

然后在這個時間前,客戶端瀏覽器都不會再發(fā)起請求,而是直接用緩存資源。

Cache-Control

Cache-Control相對比較復雜,可設置屬性也比較多,max-age只是其中一個屬性,長這樣:

Cache-Control: max-age=20000

這表示當前資源在20000秒內(nèi)都不用再請求了,直接使用緩存。

上面提到的immutable也是Cache-Control的一個屬性,但是是個實驗性質(zhì)的,各個瀏覽器兼容并不好。設置了Cache-control: immutable表示這輩子都用緩存了,再請求是不可能的了。

其他常用屬性還有:

no-cache:使用緩存前,強制要求把請求提交給服務器進行驗證(協(xié)商緩存驗證)。

no-store:不存儲有關客戶端請求或服務器響應的任何內(nèi)容,即不使用任何緩存。

另外Cache-Control還有很多屬性,大家可以參考MDN的文檔。

Expires和Cache-Control的優(yōu)先級

就一句話:如果在Cache-Control響應頭設置了 max-age 或者 s-maxage 指令,那么 Expires 頭會被忽略。

協(xié)商緩存和強制緩存優(yōu)先級

這個其實很好理解,協(xié)商緩存需要發(fā)請求跟服務器協(xié)商,強制緩存如果生效,根本就不會發(fā)請求。所以這個優(yōu)先級就是:先判斷強制緩存,如果強制緩存生效,直接使用緩存;如果強制緩存失效,再發(fā)請求跟服務器協(xié)商,看要不要使用緩存

感謝各位的閱讀,以上就是“HTTP緩存策略是什么”的內(nèi)容了,經(jīng)過本文的學習后,相信大家對HTTP緩存策略是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI