缓存服务器协议有哪些,HTTP 协议的缓存机制概述
HTTP 協(xié)議的緩存機(jī)制涉及到多個(gè)請(qǐng)求頭字段,而且整個(gè)緩存機(jī)制的細(xì)節(jié)行為也存在各種情況的差異,譬如說(shuō)什么時(shí)候訪問(wèn)本地緩存不發(fā)送請(qǐng)求,什么時(shí)候發(fā)送請(qǐng)求查看資源是否更新,獲取 response 什么情況下更新緩存等。以前我對(duì)此一知半解只是籠統(tǒng)的知道一些概念,譬如 Cache-Control 可以控制緩存的時(shí)間和是否需要緩存,但是緩存過(guò)期后的行為,有緩存后瀏覽器是否有 http 請(qǐng)求都不甚了解。所以特地 google 下,此篇是對(duì)此的知識(shí)梳理。
協(xié)議概述
什么情況下可以使用本地緩存?譬如說(shuō)我們用 get 方式請(qǐng)求了一個(gè)資源 http://mytest.domain.com/static/images/bg.png,那么我們下次再請(qǐng)求這個(gè)圖片資源的時(shí)候符合哪些條件可以使用本地緩存呢?
url 必須是 http://mytest.domain.com/static/images/bg.png,如果是 http://mytest.domain.com/static/images/bg.png?t=12312321 就會(huì)發(fā)起新的請(qǐng)求,因?yàn)?url 不同。
發(fā)送請(qǐng)求的 method 必須可被緩存,譬如 get。
第一次請(qǐng)求 response(即本地緩存)如果有一個(gè) Vary 頭,他的值列出的是一系列 http header,第二次請(qǐng)求的請(qǐng)求頭中那些在 Vary 值中所列的頭,必須和第一次請(qǐng)求相同(具體規(guī)則)。
第二次請(qǐng)求不包含請(qǐng)求頭 Pragma: no-cache
第二次請(qǐng)求不包含請(qǐng)求頭 Cache-Control: no-cache|max-age=0
第一次請(qǐng)求的 response(即本地緩存)不包含 Cache-Control: no-cache
本地緩存沒有過(guò)期
或者雖然本地緩存已經(jīng)過(guò)期,但是服務(wù)器驗(yàn)證緩存和服務(wù)器資源一致,允許使用本地緩存的情況(即獲得304 response)
注2:response header中不僅僅可以 Cache-Control: no-cache,還可以 Cache-Control: no-cache="Set-Cookie" 詳見
如何計(jì)算本地緩存是否過(guò)期
瀏覽器是通過(guò)比較緩存剩余有效時(shí)間和當(dāng)前緩存已存在時(shí)間來(lái)判斷的:response_is_fresh = (freshness_lifetime > current_age)。freshness_lifetime 取值優(yōu)先級(jí)次序如下列表所示(排在上面的優(yōu)先級(jí)越高):
Cache-Control: s-maxage=xx
Cache-Control: max-age=xx
Expires: xxxxx
按規(guī)則進(jìn)行計(jì)算(推測(cè))
注1;如果有多個(gè)重復(fù)的上述頭,那么是非法的,視作 response(資源)過(guò)期
freshness_lifetime 計(jì)算(推測(cè))規(guī)則:
規(guī)范并沒有給出具體的算法,但是給出了最壞情況(but does impose worst-case constraints on their results),如果 response(資源)有 Last-Modified 頭,那么推薦用從當(dāng)前到lastmodified這個(gè)時(shí)間段的 10% 作為 freshness_lifetime,并且 response(資源)的 current_age 如果已經(jīng)超過(guò)24小時(shí),必須在這個(gè) response 上加上113 warn-code頭。很少有瀏覽器實(shí)現(xiàn)了freshness_lifetime的自助計(jì)算(推測(cè)),所以還是還是鼓勵(lì)給出上述顯式的1 - 3三種情況。
current_age 計(jì)算規(guī)則:
泛泛來(lái)說(shuō)就是 response(資源)在本地的駐足時(shí)間加上網(wǎng)絡(luò)傳輸時(shí)間,因?yàn)榫W(wǎng)絡(luò)傳輸時(shí)間的計(jì)算有多個(gè)條件,規(guī)范實(shí)在看的我頭暈,所以具體計(jì)算規(guī)則詳見規(guī)范
本地緩存過(guò)期,如何通過(guò)服務(wù)器驗(yàn)證緩存的是否依然有效(即304的情況)
首先,如果第一次的 response(資源)頭中顯示申明了一些禁止緩存的頭(譬如:"no-store" or "no-cache" 等等),就不存在過(guò)期不過(guò)期的問(wèn)題,因?yàn)檫@個(gè)資源不允許緩存。其次,過(guò)期緩存也不一定不可用,如果在斷網(wǎng)或者第二次請(qǐng)求帶上 max-stale 這個(gè)請(qǐng)求頭,那么瀏覽器可以使用過(guò)期的緩存(masx-stale 表示在緩存過(guò)期后多少時(shí)間內(nèi)瀏覽器依然可以使用緩存)。碰到過(guò)期緩存,瀏覽器可以發(fā)送一個(gè)條件請(qǐng)求(conditional request)。這個(gè)請(qǐng)求的 url 依然是第一次請(qǐng)求的 url,只是會(huì)帶上些當(dāng)前資源的一些信息,以供服務(wù)器驗(yàn)證這個(gè)緩存是否依然可用還是需要更新:
response(資源)的 Last-Modified 頭所帶的值會(huì)放到條件請(qǐng)求的 If-Modified-Since 頭中,或者是 If-Unmodified-Since 又或者 If-Range。
response(資源)的 ETag 頭所帶的值會(huì)放到條件請(qǐng)求的 If-None-Match 頭中,或者 If-Match 又或者 If-Range。
服務(wù)器會(huì)根據(jù)不同的條件請(qǐng)求頭來(lái)驗(yàn)證資源,具體的行為詳見規(guī)范,這里不細(xì)致展開。針對(duì)條件請(qǐng)求,服務(wù)器返回會(huì)有三種情況:
一個(gè)帶有304 status code 的返回。表示緩存可以被更新和重用。
一個(gè)帶有 body 的完整的 response。表示用這個(gè) response 作為請(qǐng)求的返回,并且視條件可以用這個(gè)完整的 response 替換瀏覽器原有的緩存(此資源)。
如果返回一個(gè)5xx的 response,那么瀏覽器可以選擇就顯示這個(gè)5xx的返回,或者使用本地緩存(盡管可能是過(guò)期的)- 規(guī)范沒有規(guī)定應(yīng)該選擇哪種處理,應(yīng)該是取決于瀏覽器的行為。
如果是一個(gè)304的返回,規(guī)范說(shuō)這個(gè)返回可以更新本地緩存,更新策略分三種:
如果這個(gè)304 response 帶有資源有效性的強(qiáng)驗(yàn)證頭,那么瀏覽器會(huì)尋找本地緩存,尋找那些帶有同樣強(qiáng)驗(yàn)證頭的緩存,然后用這個(gè)最新的 response 去更新這些匹配的緩存(同一個(gè)資源可能瀏覽器保存有多份緩存,譬如日期不同等)。
如果這個(gè)304 response 帶有資源有效性的弱驗(yàn)證頭,那么瀏覽器同樣會(huì)找相匹配的緩存,但是只會(huì)更新最新的那條匹配的緩存。
如果這個(gè)304 response 沒有帶有任何資源有效性驗(yàn)證頭,并且瀏覽器緩存只有一份,并且這份也同樣沒帶有任何資源有效性驗(yàn)證頭,那么瀏覽器就會(huì)用這個(gè)304 response,更新本地緩存。
協(xié)議流程圖
假設(shè)第一次請(qǐng)求一個(gè)資源,返回 header 里面帶上如下字段:
Cache-Control: max-age=600
Last-Modified: Wed, 28 Aug 2013 10:36:42 GMT
ETag: "124752e0d85461a16e76fbdef2e84fb9"
拋開細(xì)枝末節(jié)的東西,那么第二次請(qǐng)求通常大致流程圖如下:
當(dāng)前資源緩存是否過(guò)期:response_is_fresh = (freshness_lifetime > current_age)
|
-----------------------------------
| |
是 否
| |
發(fā)送請(qǐng)求,帶上請(qǐng)求頭 從本地緩存中獲取資源(不發(fā)請(qǐng)求)
If-Modified-Since: 此資源Last-Modified的值
If-None-Match: 此資源ETag的值
|
服務(wù)器根據(jù) If-Modified-Since 和 If-None-Match
兩個(gè)值判斷資源是否更新過(guò)
|
-------------------------
| |
是 否
| |
返回一個(gè) status code:200 的 response 返回一個(gè) status code:304 的 response
response body 里面是請(qǐng)求的資源 response body 為空
| |
瀏覽器用 response body里面的資源 依然從本地緩存里面獲取資源
替換本地緩存中的資源
特殊情況
當(dāng)你去瀏覽器驗(yàn)證的時(shí)候可能會(huì)碰到一些特殊情況,就是緩存有效,但是你刷新瀏覽器依然發(fā)送的條件請(qǐng)求。其實(shí)是因?yàn)闉g覽器在請(qǐng)求頭中加入了一些料,譬如: Cache-Control: max-age=0。你刷新的方式可以有很多種,譬如:按F5,按ctrl+F5,在地址欄按回車等等。這些不同的行為都會(huì)影響瀏覽器發(fā)送請(qǐng)求的行為。這里有一些參考《在瀏覽器地址欄按回車、F5、Ctrl+F5刷新網(wǎng)頁(yè)的區(qū)別》
參考資料
總結(jié)
以上是生活随笔為你收集整理的缓存服务器协议有哪些,HTTP 协议的缓存机制概述的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 内存条兼容问题揭秘:玖合VS AMD,到
- 下一篇: 关于5G技术和5G技术即将面临的各项挑战