HTTP典型應(yīng)用于能通過采用緩存技術(shù)而提高性能的分布式信息系統(tǒng)。HTTP/1.1協(xié)議包括的許多使緩存盡可能的工作的元素。因?yàn)檫@些元素與協(xié)議的其他方面有著千絲萬(wàn)縷的聯(lián)系,而且他們相互作用、影響,因此有必要單獨(dú)的來(lái)介紹基本的緩存設(shè)計(jì)。
如果緩存不能改善性能,他將一無(wú)用處。HTTP/1.1中緩存的目的是為了在很多情況下減少發(fā)送請(qǐng)求,同時(shí)在許多情況下可以不需要發(fā)送完整響應(yīng)。前者減少了網(wǎng)絡(luò)回路(譯注:一個(gè)請(qǐng)求會(huì)返回一個(gè)響應(yīng),請(qǐng)求響應(yīng)這個(gè)過程就是一個(gè)回路)的數(shù)量;我們利用一個(gè)“過期(expiration)”機(jī)制來(lái)為此目的(見13.2節(jié))。后者減少了網(wǎng)絡(luò)應(yīng)用的帶寬;我們用“驗(yàn)證(validation)”機(jī)制來(lái)為此目的。
對(duì)行為,可行性,和關(guān)閉的操作的要求放松了語(yǔ)義透明性的目的。HTTP/1.1協(xié)議允許服務(wù)器,緩存,和客戶端能顯示地降低透明性當(dāng)在必要的時(shí)候。然而,因?yàn)椴煌该鞯牟僮髂芑煜菍I(yè)的用戶,同時(shí)可能和某個(gè)服務(wù)器應(yīng)用程序不兼容(例如訂購(gòu)商品),因此此協(xié)議透明性在下面情況下才能被放松要求:
-- 只有在一個(gè)顯示的協(xié)議層的請(qǐng)求時(shí),透明性才能被客戶端或源服務(wù)器放松
-- 當(dāng)出現(xiàn)一個(gè)對(duì)終端用戶的顯示的警告時(shí),透明性才能被緩存或被客戶端放松
因此,HTTP/1.1協(xié)議提供這些重要的元素:
1.提供完整語(yǔ)義透明的協(xié)議特征,當(dāng)這些特征被通信的所有方需要時(shí)
2. 允許源服務(wù)器或用戶代理顯示的請(qǐng)求和控制不透明操作的協(xié)議特征
3. 允許緩存給這樣的響應(yīng)綁定警告信息的協(xié)議特征,這些響應(yīng)不能保留請(qǐng)求的語(yǔ)義透明的近似
一個(gè)基本的原則是客戶端必須能夠發(fā)現(xiàn)語(yǔ)義透明性的潛在的放松。
注意:服務(wù)器,緩存,或者客戶端的實(shí)現(xiàn)者可能會(huì)面對(duì)設(shè)計(jì)上的判斷,而這些判斷沒有顯示地在此規(guī)范里討論。如果一個(gè)判斷可能會(huì)影響語(yǔ)義透明性,那么實(shí)現(xiàn)者應(yīng)該能維持語(yǔ)義透明性,除非一個(gè)仔細(xì)的完整的分析能說(shuō)明打破透明性的好處。
13.1.1緩存正確性(Cache Correctness)
一個(gè)正確的緩存必須能用最新的響應(yīng)來(lái)響應(yīng)請(qǐng)求,此響應(yīng)當(dāng)在下面的條件滿足時(shí)才適合此請(qǐng)求(見13.2.5,13.2.6,和13.12)?
此緩存響應(yīng)已被檢測(cè)與假設(shè)通過源服務(wù)器重驗(yàn)證后源服務(wù)器返回的響應(yīng)相等價(jià)。
此緩存響應(yīng)是足夠保鮮(fresh)的(見13.2節(jié))。缺省的情況下,這意味著此響應(yīng)必須滿足客戶端,源服務(wù)器,和緩存的最嚴(yán)格的保鮮要求(見14.9節(jié));如果源服務(wù)器指定了保鮮壽命,這說(shuō)明它是源服務(wù)器自己的保鮮要求。
由于客戶端和源服務(wù)器的最嚴(yán)格的保鮮要求,如果一個(gè)緩存的響應(yīng)不是足夠保鮮的,那么在仔細(xì)考慮的情況下,緩存可能仍然返回此緩存的響應(yīng)通過合適的Warning頭域(見13.1.5和14.46節(jié)),除非此響應(yīng)被阻止(例如:通過”no-store” cache-directive ,或者通過一個(gè)”no-cache”cache-request-directive;見14.9節(jié))。
此緩存響應(yīng)是一個(gè)304(沒有被改變),305(代理重定向),或 錯(cuò)誤(4xx或者5xx)響應(yīng)消息。
如果緩存不能同源服務(wù)器通信,那么一個(gè)正確的緩存應(yīng)該用它緩存的響應(yīng)去響應(yīng)請(qǐng)求,如果此緩存的響應(yīng)能正確的服務(wù)于請(qǐng)求;如果不能服務(wù)器于此請(qǐng)求,那么緩存必須能返回一個(gè)錯(cuò)誤或警告指示存在通信失敗。
如果緩存從服務(wù)器端接收到一個(gè)響應(yīng)(或者是一個(gè)完整的響應(yīng),或者一個(gè)304(沒有被改變)的響應(yīng)),此響應(yīng)應(yīng)該是正常情況下要發(fā)送到請(qǐng)求的客戶端的,并且此響應(yīng)并不是新鮮的,那么此緩存應(yīng)該把此響應(yīng)轉(zhuǎn)發(fā)給請(qǐng)求客戶端不需要添加一個(gè)新的Warning頭域(但是沒有移去已經(jīng)存在的Warning頭域)。緩存并不是簡(jiǎn)單的因?yàn)閭鬏斨许憫?yīng)變得陳舊而嘗試去重驗(yàn)證響應(yīng);這可能會(huì)導(dǎo)致一個(gè)無(wú)限的循環(huán)。用戶代理接收一個(gè)陳舊的沒有Warning頭域的響應(yīng)應(yīng)該提示用戶一個(gè)警告信息。
13.1.2警告信息(Warnings)
無(wú)論何時(shí),緩存返回一個(gè)響應(yīng),此響應(yīng)既不是第一手的(first-hand)也不是足夠保鮮(在13.1.1節(jié)的條件2),那么緩存必須利用一個(gè)Warning常用頭域來(lái)警告產(chǎn)生的效果。Warning頭域和當(dāng)前定義的警告在14.46節(jié)里描述。這些警告允許客戶端去采取合適的動(dòng)作。
警告可能被用于其他的目的,和緩存相關(guān)的目的和其他的目的。警告和錯(cuò)誤狀態(tài)碼的區(qū)別在于是否是真正的失敗。
警告被賦予三位數(shù)字warn-codes。第一個(gè)數(shù)字指明:警告是否必須或不必須從緩存項(xiàng)里刪除,在一個(gè)成功的重驗(yàn)證之后。
1xx 警告描述了響應(yīng)的保鮮或重驗(yàn)證狀態(tài)信息,并且這些信息應(yīng)該在一個(gè)成功的重驗(yàn)證之后刪除。1xx警告碼可能是由緩存產(chǎn)生的,當(dāng)緩存驗(yàn)證一個(gè)緩存項(xiàng)時(shí)。此警告碼不能被客戶端產(chǎn)生。
2xx 警告描述了實(shí)體主體或?qū)嶓w頭域的某些方面的信息,這些信息不能被重驗(yàn)證修改,并且這些信息不能在一個(gè)成功重驗(yàn)證之后被刪除。
見14.46節(jié)關(guān)于警告碼的定義。
HTTP/1.0緩存將緩存所有響應(yīng)中的警告,并且不會(huì)刪除第一類警告。穿過HTTP/1.0緩存響應(yīng)中的警告會(huì)攜帶一個(gè)額外的warning-date域,這是為了防止將來(lái)的HTTP/1.1接收端信任一個(gè)錯(cuò)誤的緩存警告。
警告同樣攜帶一個(gè)警告文本。此文本可能是任何合適的自然語(yǔ)義(可能基于客戶端請(qǐng)求的Accept頭域),同時(shí)包含一個(gè)可選擇的關(guān)于何種字符集被使用的聲明。
多個(gè)警告可能會(huì)綁定一個(gè)響應(yīng)(或者被源服務(wù)器或者被一個(gè)緩存發(fā)送的),這包括多個(gè)警告可以共用一個(gè)警告碼。例如,服務(wù)器可能會(huì)以英語(yǔ)和法語(yǔ)提供相同的警告。
當(dāng)多個(gè)警告綁定一個(gè)響應(yīng)時(shí),有時(shí)候不可能把所有的警告都展示給客戶。HTTP版本不能指定一個(gè)嚴(yán)格的優(yōu)先值去決定警告的優(yōu)先和順序顯示,但是可以探索一些方法。
13.1.3緩存控制機(jī)制 (Cache-control Mechanism)
HTTP/1.1基本的緩存機(jī)制(服務(wù)器指定過期時(shí)間和驗(yàn)證器)對(duì)緩存是隱含的指令。某些情況下,服務(wù)器或客戶端可能需要給HTTP緩存提供顯示的指令。我們利用Cache-Control頭域?yàn)榇四康摹?br />
Cache-Control頭域允許客戶端或服務(wù)器在請(qǐng)求或響應(yīng)里傳輸多個(gè)指令。這些指令常常覆蓋缺省的緩存算法。作為一個(gè)常用規(guī)則,如果頭域值中存在一個(gè)明顯的沖突,那么最具嚴(yán)格解釋的頭域值會(huì)被應(yīng)用(也就是說(shuō),能保留語(yǔ)義透明性的值)。然而,一些情況下,cache-control指令被顯示地指定用來(lái)削弱語(yǔ)義透明性的相似性(例如,”max-stale” 或者 “public”)。
Cache-control指令在14.9節(jié)被描述。
13.1.4顯示的用戶代理警告(Explicit User Agent Warnings)
很多用戶代理允許用戶覆蓋基本緩存機(jī)制。例如,用戶代理可能允許用戶指定緩存實(shí)體(即使實(shí)體明顯是陳舊的)從來(lái)不要被驗(yàn)證?;蛘撸脩舸砜赡芰?xí)慣于給任何請(qǐng)求加上“Cache-Control:max-stale=3600”。用戶代理不能缺省的執(zhí)行不透明行為,或者不能缺省的執(zhí)行導(dǎo)致非正常的無(wú)效率的緩存行為,但是可能被顯示地設(shè)置去這樣做通過一個(gè)顯示的用戶動(dòng)作。
如果用戶已經(jīng)覆蓋基本的緩存機(jī)制,那么用戶代理應(yīng)該給用戶指示何時(shí)顯示不能滿足服務(wù)器透明要求的信息(特別地,如果顯示的實(shí)體被認(rèn)為是陳舊的)。因?yàn)榇藚f(xié)議通常允許用戶代理去判定響應(yīng)是否是陳舊或不是陳舊的,所以此指示只需要當(dāng)實(shí)際發(fā)生時(shí)顯示。此指示不必是對(duì)話框;它應(yīng)該是一個(gè)圖標(biāo)(例如,一個(gè)正在腐爛的魚)或者一些其他的指示器。
如果用戶以一種方式已經(jīng)覆蓋了緩存機(jī)制,這種方式可能不正常地減少緩存效率,那么用戶代理應(yīng)該繼續(xù)指示用戶的狀態(tài)(例如,通過一個(gè)圖片顯示)以便用戶不能不注意地消費(fèi)過度的資源或者忍受過度的延遲。
13.1.5規(guī)則和警告的例外情況
在某些情況下,緩存的操作者應(yīng)該設(shè)置緩存返回陳舊的響應(yīng),即使此響應(yīng)沒有被客戶端請(qǐng)求。這個(gè)判定本來(lái)不應(yīng)該輕易決定,但是由于某些原因可能會(huì)這樣做,特別是當(dāng)緩存和源服務(wù)器連接不好時(shí)。無(wú)能何時(shí)當(dāng)緩存會(huì)返回一個(gè)陳舊的響應(yīng)時(shí),緩存必須給此響應(yīng)做個(gè)標(biāo)記(利用Warning頭域),因?yàn)檫@樣能使客戶端提示用戶響應(yīng)是陳舊的。
用戶代理照樣能采取步驟去獲得第一手的或保鮮的響應(yīng)。由于這個(gè)原因,如果客戶端顯示地請(qǐng)求第一手的或保鮮的響應(yīng),緩存就不能返回一個(gè)陳舊的響應(yīng),除非由于技術(shù)或策略方面的原因。
13.1.6由客戶控制的行為(Client-controlled Behavior)
當(dāng)源服務(wù)器是過期信息得主要來(lái)源時(shí),有時(shí)候客戶端可能需要控制緩存去判定是否返回一個(gè)緩存響應(yīng)而不需要緩存通過服務(wù)器驗(yàn)證它??蛻舳送ㄟ^利用一些Cache-Control頭域來(lái)達(dá)到此目的。
客戶端的請(qǐng)求可能會(huì)指定自己愿意接受一個(gè)沒有驗(yàn)證的響應(yīng)的最大的年齡(age);指定0值會(huì)強(qiáng)迫緩存重驗(yàn)證所有的響應(yīng)??蛻舳苏諛訒?huì)指定在響應(yīng)過期前的最小保持時(shí)間。這些選項(xiàng)增加了對(duì)緩存行為的限制,同時(shí)這樣做并不能進(jìn)一步地放松緩存語(yǔ)義透明的近似。
客戶端可能照樣會(huì)指定它會(huì)接受陳舊響應(yīng)直到陳舊數(shù)達(dá)到最大數(shù)量。這放松了對(duì)緩存的限制,同時(shí)這可能違反了源服務(wù)器指定對(duì)語(yǔ)義透明性的限制,但是這可能支持無(wú)連接的操作或者高獲得性當(dāng)連接不好時(shí)。
13.2 過期模型 (Expiration Model)
13.2.1 服務(wù)器指定模型(Server-Specified Expiratiion)?
HTTP緩存會(huì)工作的很好,這是因?yàn)榫彺婺芡耆乇苊饪蛻舳藢?duì)源服務(wù)器的請(qǐng)求。避免對(duì)源服務(wù)器請(qǐng)求的主要機(jī)制是服務(wù)器將來(lái)會(huì)提供一個(gè)顯示過期時(shí)間(explicit expiration time),此顯示過期時(shí)間用來(lái)指示響應(yīng)可能會(huì)滿足后續(xù)的請(qǐng)求。也就是說(shuō),客戶端請(qǐng)求響應(yīng)時(shí),緩存能返回一個(gè)保鮮(fresh)的響應(yīng)而不需要從源服務(wù)器那里獲得。
我們希望服務(wù)器給響應(yīng)設(shè)置顯示過期時(shí)間(explicit expiration time),服務(wù)器相信在過期時(shí)間之前實(shí)體不會(huì)改變。這能保持語(yǔ)義透明性(譯注:語(yǔ)義透明性情況1.3節(jié)里關(guān)于“語(yǔ)義透明”的解釋),只要服務(wù)器對(duì)過期時(shí)間仔細(xì)選擇。
過期機(jī)制只能應(yīng)用于能從緩存獲得的響應(yīng),不能應(yīng)用于客戶端請(qǐng)求的第一手(first-hand,見1.3節(jié)術(shù)語(yǔ))的響應(yīng)。
如果源服務(wù)器希望強(qiáng)制一個(gè)語(yǔ)義透明緩存去驗(yàn)證每個(gè)請(qǐng)求,它會(huì)使顯示過期時(shí)間(explicit expiration time)設(shè)為過去。這就是說(shuō)響應(yīng)總是陳舊的,所以此緩存應(yīng)該驗(yàn)證此響應(yīng)當(dāng)緩存利用此響應(yīng)去服務(wù)于后續(xù)的請(qǐng)求時(shí)。見14.9.4節(jié),有更多強(qiáng)迫重驗(yàn)證的方法
如果源服務(wù)器希望強(qiáng)迫任何HTTP/1.1緩存(不管此緩存是怎樣設(shè)置的)去驗(yàn)證每一個(gè)請(qǐng)求,源服務(wù)器應(yīng)該在Cache-Control頭域里指定“must-revalidate”緩存控制指令(見14.9節(jié))。
源服務(wù)器利用Expires頭域或在Cache-Control頭域里通過max-age緩存控制指令,來(lái)指定顯示過期時(shí)間(explicit expiration time)。
過期時(shí)間不能被用于強(qiáng)制客戶代理去重新刷新它的顯示或重載資源;過期的語(yǔ)義只能應(yīng)用于緩存機(jī)制,并且這個(gè)機(jī)制值只需要檢測(cè)資源的過期狀態(tài)當(dāng)請(qǐng)求那個(gè)資源的一個(gè)新請(qǐng)求發(fā)生時(shí)。見13.13節(jié),關(guān)于緩存和歷史機(jī)制的區(qū)別。
13.2.2 啟發(fā)式過期
因?yàn)樵捶?wù)器不能總是提供一個(gè)顯示過期時(shí)間(explicit expiration time),HTTP緩存通常會(huì)設(shè)置一個(gè)啟發(fā)式過期時(shí)間(heuristic expiration time),它采用一種算法,此算法利用其它的值(例如Last-Modified時(shí)間)去估計(jì)一個(gè)似乎合理的過期時(shí)間。HTTP/1.1規(guī)范沒有提供特定的算法,但是的確是加強(qiáng)了對(duì)這些算法結(jié)果的最壞情況的限制。因?yàn)閱l(fā)式過期時(shí)間可能會(huì)對(duì)語(yǔ)義透明性妥協(xié),他們本應(yīng)該被謹(jǐn)慎地使用,并且我們鼓勵(lì)源服務(wù)器盡可能提供顯示過期時(shí)間。
13.2.3 年齡(Age)計(jì)算
為了了解緩存項(xiàng)(譯注:緩存項(xiàng)是用來(lái)響應(yīng)請(qǐng)求的,它包含緩存的響應(yīng)實(shí)體)是否是保鮮的(fresh),緩存需要知道其年齡是否已超過保鮮壽命(freshness lifetime)。我們?cè)?3.2.4節(jié)中討論如何計(jì)算保鮮壽命,本節(jié)討論如何計(jì)算響應(yīng)或緩存項(xiàng)的年齡。
在此討論中我們用“now”來(lái)表示主機(jī)進(jìn)行計(jì)算時(shí)時(shí)鐘的“當(dāng)前值”。使用HTTP協(xié)議的主機(jī),特別是運(yùn)行于源服務(wù)器和緩存的主機(jī),應(yīng)該使用NTP[28] 或其他類似協(xié)議來(lái)將其時(shí)鐘同步到一個(gè)全球性的精確時(shí)間標(biāo)準(zhǔn)上。
HTTP1.1協(xié)議要求源服務(wù)器盡可能在發(fā)送每條響應(yīng)時(shí)都附加一個(gè)Date頭域,要盡可能在每個(gè)響應(yīng)里給出響應(yīng)產(chǎn)生的時(shí)間(見14.18節(jié))。我們利用術(shù)語(yǔ)“date_value”去表示Date頭域的值,這是一種適合于運(yùn)算操作的表示方法。
當(dāng)從緩存里獲取響應(yīng)消息時(shí),HTTP/1.1利用Age響應(yīng)頭域來(lái)傳送響應(yīng)消息的估計(jì)年齡。Age響應(yīng)頭域值是緩存對(duì)響應(yīng)從產(chǎn)生或被重驗(yàn)證開始到現(xiàn)在的時(shí)間估計(jì)值。
實(shí)際上,年齡的值是響應(yīng)從源服務(wù)器途徑每一個(gè)緩存的逗留時(shí)間的總和,再加上響應(yīng)在網(wǎng)絡(luò)路徑上傳輸?shù)臅r(shí)間。
我們用“age_value”來(lái)表示Age頭域的值,這是一種適于算術(shù)操作的表示方法。
一個(gè)響應(yīng)的年齡(age)可以通過兩種完全不同的途徑來(lái)計(jì)算::
如果本地時(shí)鐘與源服務(wù)器時(shí)鐘同步的相當(dāng)好,則用 now - date_value ,若結(jié)果為負(fù),則取零。
如果途徑響應(yīng)路徑(response path)的所有緩存均遵循HTTP1.1協(xié)議,則用age_value。
如果我們有兩種獨(dú)立的方法計(jì)算響應(yīng)的年齡(譯注:注意這里是響應(yīng)的年齡),我們可以合并二者如下:
corrected_received_age = max(now – date_value,age_value)?
并且只要我們或者有同步的時(shí)鐘或者響應(yīng)途徑的所有緩存遵循HTTP/1.1,我們就能得到一個(gè)可信賴的結(jié)果。
由于網(wǎng)絡(luò)附加延時(shí),一些重要時(shí)隙會(huì)在服務(wù)器產(chǎn)生響應(yīng)與下一個(gè)緩存或客戶端接收之間流逝。如果不經(jīng)修訂,這一延遲會(huì)帶來(lái)不正常的低年齡。
由于導(dǎo)致產(chǎn)生年齡值的請(qǐng)求(譯注:就是存在Age頭域的請(qǐng)求)是早于年齡值的產(chǎn)生,我們能校正網(wǎng)絡(luò)附加延遲通過記錄請(qǐng)求產(chǎn)生的時(shí)間。然后,當(dāng)一個(gè)年齡值被接收后,它必須被解釋成相對(duì)于請(qǐng)求產(chǎn)生的時(shí)間,而不是相對(duì)響應(yīng)接收的時(shí)間。不管有多少延遲,此算法會(huì)導(dǎo)致穩(wěn)定的結(jié)果。所以,我們計(jì)算:?
corrected_initial_age = corrected_received_age + (now - request_time)
這里“request_time”是請(qǐng)求的發(fā)送時(shí)間。
緩存收到響應(yīng)時(shí),它計(jì)算響應(yīng)年齡的算法如下:
/*?
* age_value?
* is the value of Age: header received by the cache with this response.?
* date_value?
* is the value of the origin server's Date: header?
* request_time?
* is the (local) time when the cache made the request?
* that resulted in this cached response?
* response_time?
* is the (local) time when the cache received the response?
* now?
* is the current (local) time?
*/?
apparent_age = max(0, response_time - date_value); //緩存收到響應(yīng)時(shí)響應(yīng)的年齡
corrected_received_age = max(apparent_age, age_value);
response_delay = response_time - request_time;?
corrected_initial_age = corrected_received_age + response_delay;?
resident_time = now - response_time; //即收到響應(yīng)到現(xiàn)在的時(shí)間間隔
current_age = corrected_initial_age + resident_time;?
緩存項(xiàng)(cache entry)的current_age是緩存項(xiàng)從被源服務(wù)器最后驗(yàn)證開始到現(xiàn)在的時(shí)間間隔(以秒記)加上corrected_initial_age。當(dāng)從緩存項(xiàng)里產(chǎn)生一條響應(yīng)時(shí),緩存必須在響應(yīng)里包含一個(gè)Age頭域,它的值應(yīng)該等于緩存項(xiàng)的current_age值。
Age頭域出現(xiàn)在響應(yīng)里說(shuō)明響應(yīng)不是第一手的(first-hand)(譯注:第一手的說(shuō)明,響應(yīng)是直接來(lái)自于源服務(wù)器到達(dá)接收端的,而不是來(lái)自于緩存里保存的副本)。然而相反的情況并不成立,因?yàn)轫憫?yīng)里缺少Age頭域并不能說(shuō)明響應(yīng)是第一手的(fisrt-hand),除非所有請(qǐng)求路徑上的緩存都遵循HTTP/1.1協(xié)議(也就是說(shuō),以前HTTP版本緩存沒有定義Age頭域)。?
13.2.4 過期計(jì)算(Expiration Calculations)
為了確定一條響應(yīng)是保鮮的(fresh)還是陳舊的(stale),我們需要將其保鮮壽命(freshness lifetime)和年齡(age)進(jìn)行比較。年齡的計(jì)算見13.2.3節(jié),本節(jié)講解怎樣計(jì)算保鮮壽命,以及判定一個(gè)響應(yīng)是否已經(jīng)過期。在下面的討論中,數(shù)值可以用任何適于算術(shù)操作的形式表示。?
我們用術(shù)語(yǔ)“expires_value”來(lái)表明Expires頭域的值。我們用術(shù)語(yǔ)“max_age_value”來(lái)表示Cache-Control頭域里“max-age”控制指令的值(見14.9.3節(jié))。
max-age指令優(yōu)于Expires頭域執(zhí)行,所以如果max-age出現(xiàn)在響應(yīng)里,那么定義如下:
freshness_lifetime = max_age_value?
否則,若Expires頭域出現(xiàn)在響應(yīng)里,定義如下:
freshness_lifetime = expires_value - date_value?
注意上述運(yùn)算不受時(shí)鐘誤差影響,因?yàn)樗行畔⒕鶃?lái)自源服務(wù)器。?
如果Expires, Cache-Control:max-age, 或 Cache-Control:s-maxage (見 14.9.3) 均未在響應(yīng)中出現(xiàn),且響應(yīng)沒有包含對(duì)緩存的其他控制,那么緩存可以用啟發(fā)式算法計(jì)算保鮮壽命(freshness lifetime)。緩存器必須對(duì)年齡大于24小時(shí)的響應(yīng)附加113警告,如果此響應(yīng)不帶這種警告。
而且,如果響應(yīng)有最后修改時(shí)間,啟發(fā)式過期值應(yīng)不大于從那個(gè)時(shí)間開始間隔的某個(gè)分?jǐn)?shù)。典型設(shè)置為間隔的10% 。
計(jì)算響應(yīng)是否過期非常簡(jiǎn)單:
response_is_fresh = (freshness_lifetime > current_age)
13.2.5澄清過期值(Disambiguation Expiration Values)
由于過期值很容易被設(shè)置,有可能兩個(gè)緩存會(huì)包含同一資源的不同保鮮值。
如果客戶端執(zhí)行請(qǐng)求接收到一個(gè)非第一手的響應(yīng),此響應(yīng)在此客戶端擁有的緩存里仍然是保鮮的,并且緩存里的緩存項(xiàng)里的Date頭域的值比此新響應(yīng)的Date頭域值要新,那么客戶端應(yīng)該忽略此響應(yīng)。如果這樣,它可能會(huì)重新以“Cache-Control:max-age=0”指令(見14.9節(jié))請(qǐng)求去強(qiáng)制任何中間緩存通過源服務(wù)器對(duì)其進(jìn)行檢查。
如果緩存對(duì)有不同驗(yàn)證器(validator)的同一個(gè)表現(xiàn)形式(representation)有兩個(gè)保鮮響應(yīng),那么緩存必須利用Date頭域值最近的響應(yīng)。這種情況可能發(fā)生由于緩存會(huì)從其他緩存得到響應(yīng),或者由于客戶端請(qǐng)求對(duì)一個(gè)保鮮緩存項(xiàng)的重載或重驗(yàn)證(revalidation)。
13.2.6澄清多個(gè)響應(yīng)(Disambiguating Multiple Response)
因?yàn)榭蛻舳丝赡苁盏浇?jīng)多個(gè)路徑而來(lái)的響應(yīng),所以有些響應(yīng)會(huì)經(jīng)過一些緩存,而其他的響應(yīng)會(huì)經(jīng)過其他的緩存,客戶端收到響應(yīng)的順序可能與源服務(wù)器發(fā)響應(yīng)的順序不同。我們希望客戶端利用最新的響應(yīng),即使舊響應(yīng)仍然是保鮮的。
實(shí)體標(biāo)簽(entity tag)和過期值都不能影響響應(yīng)的順序,因?yàn)榭赡軙?huì)出現(xiàn)晚一點(diǎn)的響應(yīng)可能會(huì)故意攜帶過早的過期時(shí)間。日期值的精度被規(guī)定只有一秒。?
當(dāng)客戶端試著重新驗(yàn)證一個(gè)緩存項(xiàng)的時(shí)候(譯注:這里的客戶端應(yīng)該包含一個(gè)本地緩存),而且接收到的響應(yīng)的Date頭域晚于已存在的緩存項(xiàng),那么客戶端應(yīng)該重新進(jìn)行無(wú)條件請(qǐng)求,并且包含
Cache-Control: max-age=0?
去強(qiáng)制任何中間緩存通過源服務(wù)器來(lái)驗(yàn)證(validate)這些中間緩存的副本,或者
Cache-Control: no-cache?
去強(qiáng)制任何中間緩存去從源服務(wù)器獲得一個(gè)新的副本。
13.3 驗(yàn)證模型(Validation Model)
當(dāng)緩存有一個(gè)舊緩存項(xiàng)并且緩存想利用此緩存項(xiàng)來(lái)作為客戶端請(qǐng)求的響應(yīng)時(shí),緩存必須首先通過源服務(wù)器(或者可能通過一個(gè)有保鮮響應(yīng)的中間緩存)對(duì)其進(jìn)行檢驗(yàn)看看此緩存項(xiàng)是否可用。我們稱做“驗(yàn)證(validating)”此緩存項(xiàng)。因?yàn)槲覀儾幌雽?duì)完整響應(yīng)的傳輸付出太大代價(jià),而且如果緩存項(xiàng)無(wú)效時(shí)也不會(huì)產(chǎn)生額外的回路(譯注:回路的意思,如:從請(qǐng)求到響應(yīng)就一條回路),HTTP1.1協(xié)議支持使用條件方法。.?
協(xié)議支持條件方法的關(guān)鍵特征是圍繞“緩存驗(yàn)證器(cache validator)”展開的。當(dāng)源服務(wù)器產(chǎn)成一個(gè)完整響應(yīng)時(shí),它同時(shí)會(huì)附加一些驗(yàn)證器給響應(yīng),這些驗(yàn)證器和緩存項(xiàng)一起保存。當(dāng)客戶端(用戶代理或緩存服務(wù)器)對(duì)對(duì)應(yīng)有緩存項(xiàng)的資源執(zhí)行條件請(qǐng)求時(shí),客戶端包含一個(gè)相關(guān)的驗(yàn)證器(validator)在請(qǐng)求里。
<br style="color:rgb(24,95,24);font-family:Georgia;font