Web開(kāi)發(fā)人員需知的Web緩存知識(shí)
什么是Web緩存,為什么要使用它?
Web緩存游走于服務(wù)器和客戶(hù)端之間。這個(gè)服務(wù)器可能是源服務(wù)器(資源所駐留的服務(wù)器Add),數(shù)量可能是1個(gè)或多個(gè);這個(gè)客戶(hù)端也可能是1個(gè)或多個(gè)。Web緩存就在服務(wù)器-客戶(hù)端之間搞監(jiān)控,監(jiān)控請(qǐng)求,并且把請(qǐng)求輸出的內(nèi)容(例如html頁(yè)面、 圖片和文件)(統(tǒng)稱(chēng)為副本)另存一份;然后,如果下一個(gè)請(qǐng)求是相同的URL,則直接請(qǐng)求保存的副本,而不是再次麻煩源服務(wù)器。
使用緩存的2個(gè)主要原因:
- 降低延遲:緩存離客戶(hù)端更近,因此,從緩存請(qǐng)求內(nèi)容比從源服務(wù)器所用時(shí)間更少,呈現(xiàn)速度更快,網(wǎng)站就顯得更靈敏。
- 降低網(wǎng)絡(luò)傳輸:副本被重復(fù)使用,大大降低了用戶(hù)的帶寬使用,其實(shí)也是一種變相的省錢(qián)(如果流量要付費(fèi)的話),同時(shí)保證了帶寬請(qǐng)求在一個(gè)低水平上,更容易維護(hù)了。
Web緩存的類(lèi)型
1. 瀏覽器緩存
在任何現(xiàn)代瀏覽器上(如IE, FireFox, Chrome)折騰清除隱私數(shù)據(jù)(//zxx: 原文說(shuō)的是首選項(xiàng),顯然out了,這里有改動(dòng))的對(duì)話框,你很可能會(huì)注意到“緩存”這個(gè)設(shè)置項(xiàng)。
瀏覽器會(huì)在你的硬盤(pán)上專(zhuān)門(mén)開(kāi)辟一個(gè)空間專(zhuān)門(mén)為你存儲(chǔ)資源副本。瀏覽器緩存的工作規(guī)則很簡(jiǎn)單:檢查以確保副本是最新的,通常只要一次會(huì)話(就是當(dāng)前瀏覽器調(diào)用的這次N)。
瀏覽器緩存在用戶(hù)觸發(fā)“后退”操作或點(diǎn)擊一個(gè)之前看過(guò)的鏈接的時(shí)候很管用。同樣,如果你在網(wǎng)站上訪問(wèn)同一張圖片,該圖片可以從瀏覽器緩存中調(diào)出并幾乎立即顯現(xiàn)出來(lái)。
2. 代理服務(wù)器緩存
Web代理服務(wù)器使用同樣的緩存原理,只是規(guī)模更大。代理以同樣的方式服務(wù)千萬(wàn)用戶(hù),大公司和ISP(Internet Server Provider, Internet服務(wù)提供商Add)經(jīng)常在他們的防火墻或者單獨(dú)的設(shè)備(也被稱(chēng)為中介(intermediaries))上架設(shè)代理緩存。
由于代理服務(wù)器緩存并非客戶(hù)端或者源服務(wù)器的一部分,而是處于網(wǎng)絡(luò)中,請(qǐng)求需要以某種方式路由到它們。一種方法是手動(dòng)設(shè)置,告訴瀏覽器的你常用的代理服務(wù)器(//zxx: 翻墻的時(shí)候常用的),另外就是使用攔截。攔截代理(Interception proxies)把Web請(qǐng)求根據(jù)自己的底層網(wǎng)絡(luò)重定向,因此,客戶(hù)端無(wú)需配置,甚至都不需要知道它們。//zxx: 維基百科上提供的幾種檢測(cè)攔截代理服務(wù)器存在的方法add,您若有興趣,可以點(diǎn)擊這里查看。
代理緩存屬于一種共享緩存;往往有大量的用戶(hù)使用,因此,其在降低延時(shí)和網(wǎng)絡(luò)流量上很有用,畢竟每個(gè)副本都被大量重用。//zxx: 這里我有疑問(wèn):就算是放在代理服務(wù)器上,每次獲取還是要通過(guò)網(wǎng)絡(luò)的啊,如何降低了網(wǎng)絡(luò)流量呢?希望誰(shuí)可以幫忙解惑下。
3. 網(wǎng)關(guān)緩存
也被稱(chēng)為“反向代理緩存”或“替代緩存”。網(wǎng)關(guān)緩存同樣是起中介作用的,不過(guò)不是(素不相識(shí)、不曾謀面的Add)網(wǎng)絡(luò)管理員部署的,而多半是網(wǎng)站管理員(公司專(zhuān)門(mén)的運(yùn)維工程師、或UED或程序組某人Add)他們自己部署,這樣更容易擴(kuò)展與維護(hù)。
可以有多種方法把請(qǐng)求路由到網(wǎng)關(guān)緩存,但通常使用某種形式的負(fù)載均衡器①,使它們中的一個(gè)或多個(gè)看起來(lái)像是源服務(wù)器。內(nèi)容分發(fā)網(wǎng)絡(luò)②(CDNs)為整個(gè)網(wǎng)絡(luò)(或部分)分配網(wǎng)關(guān)緩存,然后把這些緩存賣(mài)給需要的網(wǎng)站。Speedera③和Akamai④就是代表性的網(wǎng)絡(luò)內(nèi)容發(fā)布商。
①負(fù)載均衡器:是一種采用各種分配算法把網(wǎng)絡(luò)請(qǐng)求分散到一個(gè)服務(wù)器集群中的可用服務(wù)器上去,通過(guò)管理進(jìn)入的Web數(shù)據(jù)流量和增加有效的網(wǎng)絡(luò)帶寬,從而使網(wǎng)絡(luò)訪問(wèn)者獲得盡可能最佳的聯(lián)網(wǎng)體驗(yàn)的硬件設(shè)備。
②內(nèi)容分發(fā)網(wǎng)絡(luò):即CDN, 基本思路是盡可能避開(kāi)互聯(lián)網(wǎng)上有可能影響數(shù)據(jù)傳輸速度和穩(wěn)定性的瓶頸和環(huán)節(jié),使內(nèi)容傳輸?shù)母?、更穩(wěn)定。通過(guò)在網(wǎng)絡(luò)各處放置節(jié)點(diǎn)服務(wù)器所構(gòu)成的在現(xiàn)有的互 聯(lián)網(wǎng)基礎(chǔ)之上的一層智能虛擬網(wǎng)絡(luò),CDN系統(tǒng)能夠?qū)崟r(shí)地根據(jù)網(wǎng)絡(luò)流量和各節(jié)點(diǎn)的連接、負(fù)載狀況以及到用戶(hù)的距離和響應(yīng)時(shí)間等綜合信息將用戶(hù)的請(qǐng)求重新導(dǎo)向 離用戶(hù)最近的服務(wù)節(jié)點(diǎn)上。其目的是使用戶(hù)可就近取得所需內(nèi)容,解決 Internet網(wǎng)絡(luò)擁擠的狀況,提高用戶(hù)訪問(wèn)網(wǎng)站的響應(yīng)速度。
③Speedera:是一家全球性的內(nèi)容服務(wù)提供商,它與北美、歐洲以及亞太地區(qū)的1000多家大型運(yùn)營(yíng)商都有聯(lián)系,并為那些不想在自己服務(wù)器上寄存內(nèi)容的公司提供軟件下載、媒體及其它服務(wù)管理等業(yè)務(wù)。05年的時(shí)候被下面要介紹的Akamai以$130m的價(jià)格給收購(gòu)了。
④Akamai:美國(guó)Akamai是國(guó)際上最大的CDN服務(wù)商,它巨大的網(wǎng)絡(luò)分發(fā)能力在峰值時(shí)可達(dá)到15Tbps。 Akamai公司是為數(shù)不多的旨在消除Internet瓶頸和提高下載速度的幾家新公司之一,是一個(gè)致力于網(wǎng)絡(luò)交通提速的”內(nèi)容發(fā)布”公司,是波士頓高技 術(shù)區(qū)最卓越的新興企業(yè)之一。Akamai公司向全球企業(yè)提供發(fā)送互聯(lián)網(wǎng)內(nèi)容,匯流媒體和應(yīng)用程序的服務(wù)(目前,該公司為15個(gè)國(guó)家的企業(yè)管理著8000多 臺(tái)服務(wù)器)。1998年,丹尼爾。L和麻省理工學(xué)院的一些研究人員一起創(chuàng)立了這家公司,他在麻省理工學(xué)院的碩士論文構(gòu)成了Akamai公司最初的”自由 流”(Freeflow)技術(shù)的核心。
本教程重點(diǎn)在瀏覽器和代理緩存,盡管有些信息對(duì)網(wǎng)關(guān)緩存感興趣的人也適用。
Web緩存無(wú)害嗎?為什么要鼓勵(lì)緩存?
Web緩存是互聯(lián)網(wǎng)中最容易被誤解的技術(shù)之一。網(wǎng)站管理員特別希望知道網(wǎng)站的一舉一動(dòng),比方說(shuō)多少人訪問(wèn)啦,訪問(wèn)時(shí)間啊什么的,而緩存會(huì)“隱藏”他們的用戶(hù),他們就無(wú)從得知到底誰(shuí)訪問(wèn)了這個(gè)站點(diǎn)。
撿了芝麻丟西瓜,自認(rèn)為放棄緩存可以精確跟蹤用戶(hù),實(shí)際上,互聯(lián)網(wǎng)中有太多的變數(shù),想精確得到一張用戶(hù)查看網(wǎng)站的圖片?沒(méi)那么簡(jiǎn)單的,親!如果你很重視這個(gè)問(wèn)題,恭喜你,本文正好提供了解決之道,即保證緩存友好,同時(shí)又能獲得統(tǒng)計(jì)。
另外需要注意的是,緩存的內(nèi)容都是舊的過(guò)時(shí)的。因此,如何準(zhǔn)確更新就成了一個(gè)問(wèn)題。不過(guò)不要擔(dān)心,本文會(huì)向你展示如何配置服務(wù)器,讓緩存就像你的女仆——隨便調(diào)教。
CDN算是個(gè)挺有意思的技術(shù),不同于代理緩存,CDN的網(wǎng)關(guān)緩存和被緩存的Web站點(diǎn)的利益是一致的,因此,上面提到的問(wèn)題對(duì)于CDN而言是沒(méi)有的。不過(guò),即使你使用了CDN,你仍要顧慮下游的代理和瀏覽器緩存。
以上為緩存可能的“糟粕”,那他好的地方呢?緩存可以讓你的Web站點(diǎn)加載更快,讓你的服務(wù)器和互聯(lián)網(wǎng)鏈接間負(fù)擔(dān)更小。這種差異會(huì)導(dǎo)致一些類(lèi)似質(zhì)的 變化,一個(gè)網(wǎng)站要幾秒鐘才能加載出來(lái),而另外一個(gè)充分發(fā)揮緩存的優(yōu)勢(shì),幾乎瞬間顯示。用戶(hù)自然更喜歡那個(gè)加載迅速的站點(diǎn),訪問(wèn)也更多。
再說(shuō)個(gè)現(xiàn)實(shí)示例,許多大型互聯(lián)網(wǎng)公司花費(fèi)了數(shù)百萬(wàn)美元,在世界各地設(shè)立服務(wù)器集群來(lái)復(fù)制他們的內(nèi)容,以使其盡可能快被他們的用戶(hù)訪問(wèn)。緩存為你做同樣的事情,而且他們更接近最終用戶(hù)。最重要的是,你不要花銀子。
實(shí)際上呢,無(wú)論你喜歡與否,代理和瀏覽器緩存都會(huì)被使用。如果你站點(diǎn)的緩存配置不正確,你只能聽(tīng)天由命了。
#p#
Web緩存如何工作
所以的緩存都有一套自己的規(guī)則,可以用來(lái)決定何時(shí)跟緩存曖昧往來(lái)。其中部分規(guī)則設(shè)定在協(xié)議中(HTTP 1.0 以及 1.1),部分由緩存管理員⑤設(shè)置。
⑤緩存管理員:如果指的是瀏覽器緩存,則有可能就是我們服務(wù)器專(zhuān)家同事,在服務(wù)器上配置一些緩存規(guī)則;如果是代理緩存,則指的就是處理代理服務(wù)器這塊的管理人員。
一般而言有如下常用規(guī)則N:
- 如果請(qǐng)求信息是需要認(rèn)證或者安全加密的(如, HTTPS),相應(yīng)內(nèi)容也不會(huì)被緩存;
- 緩存如果有以下表現(xiàn),則認(rèn)為是fresh新鮮的(無(wú)需檢查源服務(wù)器,直接發(fā)送給客戶(hù)端):
- 含有完整的過(guò)期時(shí)間和壽命控制頭信息,并且內(nèi)容仍在保鮮期內(nèi),或者
- 緩存最近已展現(xiàn),并且在不久前修改。則內(nèi)容緩存直取,繞過(guò)源服務(wù)器。
- 若內(nèi)容陳舊,則會(huì)要求源服務(wù)器做驗(yàn)證 validate ,或者告訴緩存其拷貝副本是否是OK的。
- 特定情況下——例如,斷網(wǎng)了,之前有過(guò)的響應(yīng)緩存直取而不檢查源服務(wù)器。
響應(yīng)如果沒(méi)有類(lèi)似ETag或Last-Modified頭這樣的校驗(yàn)器,也沒(méi)有明確的更新信息,通常(并不絕對(duì))認(rèn)為是不可緩存的。
總而言之,新鮮度freshness和校驗(yàn)validation是確定緩存內(nèi)容是否可用的最重要途徑。如果要展示的足夠新,直接緩存??;如果檢測(cè)發(fā)現(xiàn)展示內(nèi)容并未變化,則不會(huì)再來(lái)一次完整的傳輸。
如何控制緩存和不緩存
有很多工具可以幫助設(shè)計(jì)師和網(wǎng)站管理員調(diào)整服務(wù)器緩存網(wǎng)站的方式,這也許需要你親自動(dòng)手對(duì)服務(wù)器的配置進(jìn)行一些調(diào)整,但絕對(duì)值得。了解如何使用這些工具請(qǐng)參考本文后面的章節(jié)。
HTML Meta標(biāo)簽 vs. HTTP頭信息
HTML重構(gòu)人員可以在文檔的<head>
中添加標(biāo)簽進(jìn)行描述。這些meta標(biāo)簽通常用來(lái)標(biāo)記不可緩存或過(guò)期時(shí)間。
Meta標(biāo)簽使用簡(jiǎn)單,但效果一般。因?yàn)橹槐簧贁?shù)幾個(gè)瀏覽器寵幸,而代理緩存基本上就不訪問(wèn)HTML文檔。盡管我們可以在頁(yè)面上試圖添加no-cache
meta標(biāo)簽讓頁(yè)面一直是最新的,但其實(shí)沒(méi)必要。
如果你的網(wǎng)站托管在ISP或者主機(jī)托管商那里,并且他們沒(méi)有賦予您任意設(shè)置HTTP頭信息的能力(比如Expires和Cache-Control),你要投訴爭(zhēng)取,因?yàn)樵谀愕墓ぷ髦羞@些是必須的。
另外一方面: HTTP頭信息可以讓你對(duì)瀏覽器和代理服務(wù)器如何處理你的副本進(jìn)行更多的控制。他們?cè)贖TML代碼中是看不見(jiàn)的, 一般由Web服務(wù)器自動(dòng)生成。但是,根據(jù)你使用的服務(wù)器,你可以在某種程度上進(jìn)行控制。在下文中:你將看到一些有趣的HTTP頭信息,以及如何在你的站點(diǎn) 上應(yīng)用部署這些特性。
HTTP頭信息發(fā)送在HTML代碼之前,只能被瀏覽器和一些中間緩存能看到,一個(gè)典型的HTTP 1.1協(xié)議返回的頭信息看上去像這樣:
HTTP/1.1 200 OK Date: Fri, 30 Oct 1998 13:19:41 GMT Server: Apache/1.3.3 (Unix) Cache-Control: max-age=3600, must-revalidate Expires: Fri, 30 Oct 1998 14:19:41 GMT Last-Modified: Mon, 29 Jun 1998 02:28:12 GMT ETag: "3e86-410-3596fbbc" Content-Length: 1040 Content-Type: text/html
頭信息空一行后是HTML代碼的輸出,關(guān)于如何設(shè)置HTTP頭信息請(qǐng)參考對(duì)應(yīng)章節(jié)。
Pragma HTTP頭信息(以及為什么不起作用)
很多人認(rèn)為在HTTP頭信息中設(shè)置了Pragma: no-cache
后會(huì)讓內(nèi)容無(wú)法被緩存。但事實(shí)并非如此:HTTP的規(guī)范 中,響應(yīng)型頭信息沒(méi)有任何關(guān)于Pragma屬性的說(shuō)明,只說(shuō)明了請(qǐng)求頭信息(瀏覽器發(fā)送給服務(wù)器的頭信息)中的Pragma屬性。雖然有少部分緩存會(huì)買(mǎi) 賬,但大部分無(wú)視,使用Pragma沒(méi)作用。若要使用,試試下面的頭信息。
使用Expires HTTP頭信息控制不過(guò)期
Expires HTTP頭是控制緩存的基本手段,Expires的中文意思是“有效期”,顯然,就是告訴瀏覽器緩存的有效期。如果過(guò)期,緩存會(huì)檢查源服務(wù)器以確定文件是否改變了。Expires頭幾乎每個(gè)緩存都支持。
大部分的服務(wù)器允許你以多種方式設(shè)置Expires響應(yīng)頭。通常,他們?cè)试S設(shè)置一個(gè)絕對(duì)過(guò)期時(shí)間,然后對(duì)比最后一次訪問(wèn)的時(shí)候或者最后一次文檔修改的時(shí)候決定客戶(hù)端內(nèi)容的獲取方式。
對(duì)于靜態(tài)圖片(如導(dǎo)航或按鈕的圖片)而言,Expires頭信息是相當(dāng)有用的,因?yàn)閳D片不怎么修改,您可以給圖片設(shè)置一個(gè)相當(dāng)長(zhǎng)的過(guò)期時(shí)間,這回讓 你的用戶(hù)感覺(jué)網(wǎng)站變快了。Expires對(duì)于控制有改變規(guī)律的網(wǎng)頁(yè)也很有用,例如:你有一個(gè)新聞聚合頁(yè)面,每天早上6點(diǎn)鐘準(zhǔn)時(shí)更新,您可以設(shè)置緩存的過(guò)期 時(shí)間也是這個(gè)點(diǎn),于是緩存就可以很聰明地知道什么時(shí)候該去重載新的內(nèi)容,什么時(shí)候睡大覺(jué)。
Expires頭唯一的有效值是HTTP時(shí)間,其他值都會(huì)被認(rèn)為是“前男友前女友”之類(lèi),不會(huì)去緩存的。注意:時(shí)間是格林威治時(shí)間(GMT),而不是本地時(shí)間。如下所示:
Expires: Fri, 30 Oct 1998 14:19:41 GMT
顯然,如果你要使用Expires頭,確保你的Web服務(wù)器時(shí)間的準(zhǔn)備就非常重要了。使用網(wǎng)絡(luò)時(shí)間協(xié)議⑥(Network Time Protocol – NTP)不失為一個(gè)號(hào)方法。如果你的身邊有本地系統(tǒng)管理員,可以向他咨詢(xún),或者查看下面的百科Add 。
盡管Expires頭很有用,但它有一定的局限性。首先,因?yàn)闋砍兜綍r(shí)間,Web服務(wù)器端的時(shí)鐘必須和緩存的同步,否則很可能實(shí)現(xiàn)不了預(yù)期的結(jié)果——緩存把前女友當(dāng)初現(xiàn)女友,把現(xiàn)女友當(dāng)作過(guò)去式——那就悲劇了。
另外一個(gè)問(wèn)題是,你很容易忘記給某內(nèi)容設(shè)置了一個(gè)特定時(shí)間,如果返回內(nèi)容的時(shí)候沒(méi)有更新這個(gè)過(guò)期時(shí)間,則每個(gè)請(qǐng)求都是上訪到服務(wù)器,反而增加了負(fù)載和響應(yīng)時(shí)間。
⑥網(wǎng)絡(luò)時(shí)間協(xié)議(NTP): 以封包交換把兩臺(tái)電腦的時(shí)鐘同步化的網(wǎng)絡(luò)協(xié)議。NTP使用UDP端口123作為傳輸層。它是用作抵銷(xiāo)可變延遲的影響。NTP是仍在使用中的最古老的網(wǎng)絡(luò)協(xié) 議之一(在1985年前開(kāi)始)。NTP最初由德拉瓦州大學(xué)的Dave Mills設(shè)計(jì),他與一群志愿者仍在維護(hù)NTP。
Cache-Control(緩存控制)HTTP頭信息
HTTP 1.1引入了新的頭信息:Cache-Control
響應(yīng)頭信息,讓網(wǎng)站的發(fā)布者可以更全面的控制他們的內(nèi)容,更好地處理Expires的些限制。Cache-Control
有用的響應(yīng)頭包括:
- max-age=[秒]:表示在這個(gè)時(shí)間范圍內(nèi)緩存是新鮮的無(wú)需更新。類(lèi)似Expires時(shí)間,不過(guò)這個(gè)時(shí)間是相對(duì)的,而不是絕對(duì)的。也就是某次請(qǐng)求成功后多少秒內(nèi)緩存是新鮮的。
- s-maxage=[秒]:類(lèi)似
max-age
, 除了僅應(yīng)用于共享緩存(如代理)。 - public:標(biāo)記認(rèn)證的響應(yīng)才能夠被緩存。一般而言,需要認(rèn)證HTTP請(qǐng)求內(nèi)容會(huì)自動(dòng)私有化(不會(huì)被緩存Add)。
- privateN:允許緩存專(zhuān)門(mén)為某一個(gè)用戶(hù)存儲(chǔ)響應(yīng),比方說(shuō)在瀏覽器中;共享緩存一般不會(huì),例如在代理中。
- no-cache:每次在釋放緩存副本之前都強(qiáng)制發(fā)送請(qǐng)求給源服務(wù)器進(jìn)行驗(yàn)證,這在確保認(rèn)證有效性上很管用(和
public
結(jié)合使用)或者保證內(nèi)容必須是即時(shí)的,不得無(wú)視緩存的所有優(yōu)點(diǎn),如國(guó)內(nèi)的微博、twitter等的刷新顯示Add。 - no-store:強(qiáng)制緩存在任何情況下都不要保留任何副本。
- must-revalidate:告訴緩存,我給你準(zhǔn)備了一些關(guān)于新鮮度的信息,在表現(xiàn)的時(shí)候要嚴(yán)格遵循之。HTTP允許緩存在某些特定情況下返回過(guò)期數(shù)據(jù),指定了這個(gè)屬性,相對(duì)于告訴緩存,你丫必須嚴(yán)格遵循我的規(guī)則。
- proxy-revalidate:類(lèi)似
must-revalidate
,除了只能應(yīng)用于代理緩存。
舉個(gè)板栗:
Cache-Control: max-age=3600, must-revalidate
如果Cache-Control
和Expires
同時(shí)存在,Cache-Control
說(shuō)了算N。如果你打算使用Cache-Control
頭,你應(yīng)該好好看看”HTTP 1.1 規(guī)范“, 詳見(jiàn)參考文章以及拓展閱讀。
驗(yàn)證器和驗(yàn)證
在緩存如何工作這段譯文中,我們說(shuō)過(guò),服務(wù)器以及緩存通過(guò)驗(yàn)證來(lái)判斷內(nèi)容是否改變,在不確定內(nèi)容是否過(guò)期的時(shí)候,可以避免本地已經(jīng)存在副本的時(shí)候下載整個(gè)內(nèi)容。
驗(yàn)證器是很重要的,如果一個(gè)都沒(méi)有,同時(shí)沒(méi)有可用的新鮮度信息(Expires
或Cache-Control
),緩存一點(diǎn)兒都不會(huì)存儲(chǔ)內(nèi)容。
最常見(jiàn)的驗(yàn)證是通過(guò)Last-Modified
頭信息通信確定文檔最后的修改時(shí)間,如果緩存有內(nèi)容存儲(chǔ),會(huì)包含Last-Modified
信息的,輔助If-Modified-Since
請(qǐng)求,我們可以詢(xún)問(wèn)服務(wù)器內(nèi)容是否改變了。
HTTP 1.1引入了一個(gè)新的驗(yàn)證器,稱(chēng)為Etag
⑦. Etag
是每次展現(xiàn)內(nèi)容改變時(shí)候由服務(wù)器生成的唯一標(biāo)識(shí)符,由于服務(wù)器控制ETag
如何生成,當(dāng)緩存發(fā)起If-None-Match
請(qǐng)求的時(shí)候,如果Etag
匹配,就可以確定展示內(nèi)容其實(shí)是一樣的。
⑦Etag: HTTP協(xié)議規(guī)格說(shuō)明定義ETag為”被請(qǐng)求變量的實(shí)體值”。另一種說(shuō)法是,ETag是一個(gè)可以與Web資源關(guān)聯(lián)的記號(hào)(token)。典型的Web資源 可以一個(gè)Web頁(yè),但也可能是JSON或XML文檔。服務(wù)器單獨(dú)負(fù)責(zé)判斷記號(hào)是什么及其含義,并在HTTP響應(yīng)頭中將其傳送到客戶(hù)端,以下是服務(wù)器端返回 的格式:ETag:”50b1c1d4f775c61:df3″客戶(hù)端的查詢(xún)更新格式是這樣的:If-None-Match : W / “50b1c1d4f775c61:df3″如果ETag沒(méi)改變,則返回狀態(tài)304然后不返回,這也和Last-Modified一樣。測(cè)試Etag主要 在斷點(diǎn)下載時(shí)比較有用。
幾乎所有的緩存使用Last-Modified
時(shí)間作為驗(yàn)證器,Etag
驗(yàn)證也開(kāi)始變得流行。
所有新一代的Web服務(wù)器都對(duì)靜態(tài)內(nèi)容(如:文件)自動(dòng)生成ETag
和Last-Modified
頭信息,而你不必做任何設(shè)置。但是,服務(wù)器對(duì)于動(dòng)態(tài)內(nèi)容(例如:CGI, ASP或數(shù)據(jù)庫(kù)生成的網(wǎng)站)并不知道如何生成這些信息,參考一下編寫(xiě)支持緩存的腳本章節(jié);
創(chuàng)建支持緩存網(wǎng)站的小技巧
除了使用新鮮度信息以及驗(yàn)證,還有其他一些技巧可以讓你網(wǎng)站的緩存更加友好:
- 保持URL穩(wěn)定:這是緩存的金科玉律,如果你為不同頁(yè)面,不同用戶(hù)或不同網(wǎng)站提供相同的內(nèi)容,他們應(yīng)該使用相同的URL. 這是簡(jiǎn)單卻非常行之有效的方法。例如,你的HTML中的某個(gè)引用地址是
"/index.html"
, 則要一直使用這個(gè)地址。 - 不同地方的圖片和其他元素使用同一庫(kù)。
- 對(duì)于不經(jīng)常改變的圖片/頁(yè)面啟用緩存,通過(guò)將
Cache-Control: max-age
頭信息的值設(shè)大一點(diǎn)。 - 對(duì)于定期更新的內(nèi)容通過(guò)指定
max-age
或過(guò)期時(shí)間實(shí)現(xiàn)緩存。 - 如果資源改變了(尤其下載文件),改變其名字。由于一般這種資源會(huì)有很長(zhǎng)的過(guò)期時(shí)間,而服務(wù)器上一直是正確的版本;因此,鏈接這個(gè)下載資源的頁(yè)面需要要比較短的過(guò)期時(shí)間(//zxx: 我司頁(yè)面5分鐘過(guò)期)。否則,會(huì)出現(xiàn)服務(wù)器的資源是新的,但頁(yè)面被緩存了,其中的鏈接地址還是舊的,就會(huì)出現(xiàn)新舊版本沖突的可能Add。
- 萬(wàn)不得已不要變動(dòng)文件:否則你要設(shè)置一個(gè)新的
Last-Modified
值。另外,當(dāng)你更新站點(diǎn)的時(shí)候,只要上傳改動(dòng)的那些文件,而不要把整個(gè)站點(diǎn)都覆蓋過(guò)去。 - Cookie能不用就不用:Cookie難以被緩存,且大多情境下是沒(méi)有必要的。如果你非得使用Cookie,建議用在動(dòng)態(tài)頁(yè)面上。
- 減少SSL⑧的使用:因?yàn)楣蚕砭彺娌荒艽鎯?chǔ)認(rèn)證頁(yè)面,只在必要的時(shí)候使用,并且在SSL頁(yè)面上減少圖片的使用。
- 使用REDbot⑨檢查你的網(wǎng)站:可以幫助你應(yīng)用本文所介紹的一些概念。
⑧ SSL:全稱(chēng)Secure Socket Layer – 安全套接層,為Netscape所研發(fā),用以保障在Internet上數(shù)據(jù)傳輸之安全,利用數(shù)據(jù)加密(Encryption)技術(shù),可確保數(shù)據(jù)在網(wǎng)絡(luò)上之 傳輸過(guò)程中不會(huì)被截取及竊聽(tīng)。目前一般通用之規(guī)格為40 bit之安全標(biāo)準(zhǔn),美國(guó)則已推出128 bit之更高安全標(biāo)準(zhǔn),但限制出境。只要3.0版本以上之I.E.或Netscape瀏覽器即可支持SSL。
⑨ REDbot:REDbot = RED + robot,是個(gè)機(jī)器人,檢查HTTP資源,看他們?nèi)绾螘?huì)表現(xiàn),指出常見(jiàn)的問(wèn)題,并提出改進(jìn)建議。雖然它屬于HTTP一致性測(cè)試儀,但卻可以找到不少HTTP相關(guān)問(wèn)題。
#p#
編寫(xiě)支持緩存的腳本
默認(rèn)情況下,大多數(shù)的腳本不會(huì)返回驗(yàn)證器(Last-Modified
或Etag
響應(yīng)頭)或新鮮度信息(Expires
或Cache-Control
)。盡管有些腳本的確是動(dòng)態(tài)的(意味著每次請(qǐng)求都有不同的響應(yīng)),還是有很多(如搜索引擎或數(shù)據(jù)庫(kù)驅(qū)動(dòng)的)網(wǎng)站可以從緩存中受益。
一般來(lái)講,對(duì)于同一個(gè)請(qǐng)求(無(wú)論是幾分鐘還是幾天之后),如果腳本產(chǎn)生的內(nèi)容是可重復(fù)的,則可以緩存。腳本內(nèi)容的改變僅僅依賴(lài)于URL,則可以緩存。如果是依賴(lài)于Cookie,認(rèn)證信息或其他外部條件,很可能不緩存。
- 最利于緩存的腳本就是在內(nèi)容改變時(shí)導(dǎo)出成靜態(tài)文件,服務(wù)器會(huì)想對(duì)待其他Web一樣對(duì)待它的,生成以及使用驗(yàn)證器,于是你可以好好地喝杯咖啡了。記住,只有文件更改的時(shí)候才寫(xiě)入,這樣Last-Modified時(shí)間就會(huì)被保存下來(lái)。
- 另外的腳本緩存之道就是使用
age
相關(guān)的頭部,相比Expires
,Cache-Control: max-age
更容易些,因?yàn)槭窍鄬?duì)時(shí)間,每次新請(qǐng)求完成后重新設(shè)置,時(shí)間到了,再重新請(qǐng)求,再設(shè)置新的相對(duì)過(guò)期時(shí)間。 - 如果上面的做法你搞不定,你還可以試試通過(guò)腳本生成一個(gè)校驗(yàn)器, 然后回應(yīng)
If-Modified-Since
和/或If-None-Match
請(qǐng)求。通過(guò)分析HTTP頭信息,在適合的時(shí)候回應(yīng)304 Not Modified
. 不幸的是,這不是個(gè)打打醬油就能搞定的任務(wù)。
其他一些技巧
- 不要使用POST:若是獲取數(shù)據(jù),盡量不使用POST模式,因?yàn)镻OST方式返回內(nèi)容大部分不會(huì)被緩存,相對(duì)的,通過(guò)GET以路徑和查詢(xún)發(fā)送的信息被緩存存儲(chǔ)下來(lái)供后續(xù)使用。
- URL地址中不要嵌入特定的用戶(hù)信息,除非生成的內(nèi)容對(duì)于用戶(hù)而言是唯一的。
- 不要指望同一用戶(hù)的所有請(qǐng)求來(lái)自同一主機(jī),因?yàn)榫彺娼?jīng)常協(xié)同工作。//zxx: 嘛意思?
- 生成Content-Length⑩頭信息。實(shí)現(xiàn)不難,可讓你的腳本以持久連接(persistent connection)形式響應(yīng)。這允許客戶(hù)端在一個(gè)TCP/IP請(qǐng)求上請(qǐng)求多個(gè)內(nèi)容,而不是為每次請(qǐng)求單獨(dú)建立連接,這樣你的網(wǎng)站相應(yīng)會(huì)快很多。
詳見(jiàn)實(shí)現(xiàn)注意事項(xiàng)。
⑩Content-Length:指明實(shí)體正文的長(zhǎng)度,以字節(jié)方式存儲(chǔ)的十進(jìn)制數(shù)字來(lái)表示。在數(shù)據(jù)下行的過(guò)程中,Content-Length的方式要預(yù)先在服務(wù)器中緩存所有數(shù)據(jù),然后所有數(shù)據(jù)再一股腦兒地發(fā)給客戶(hù)端。
常見(jiàn)問(wèn)題解答
緩存可用的最重要事情是?
其中一個(gè)不錯(cuò)的策略是找出常用的、規(guī)模較大的內(nèi)容(尤其圖片),然后優(yōu)先處理之。
我該如何利用緩存讓我的頁(yè)面盡可能的快?
最應(yīng)該緩存的內(nèi)容設(shè)置一個(gè)較長(zhǎng)的過(guò)期時(shí)間。驗(yàn)證有助于減少查看內(nèi)容的時(shí)間,不過(guò)緩存仍會(huì)連接源服務(wù)器查看是不是過(guò)期了。如果緩存已經(jīng)知道內(nèi)容是新鮮的,直接返回。
我知道緩存是個(gè)好東西,但是我想隨時(shí)知道多少人訪問(wèn)了我的網(wǎng)頁(yè)!
如果你必須知道每一次頁(yè)面被訪問(wèn)的情況,可以選擇頁(yè)面上的一個(gè)小元素(或頁(yè)面本身),然后給這個(gè)元素一個(gè)適當(dāng)?shù)念^信息使它是不可緩存。比如,你可以在每一個(gè)頁(yè)面上引用一個(gè)1像素×1像素的不可緩存(如scr地址后面加個(gè)隨機(jī)數(shù)Add)的透明圖片。Referer頭信息將會(huì)包含調(diào)用它的頁(yè)面信息。
請(qǐng)注意,即使這樣也不能給出你用戶(hù)的精確統(tǒng)計(jì),并且對(duì)通過(guò)互聯(lián)網(wǎng)訪問(wèn)的用戶(hù)也不是很友好:產(chǎn)生不必要的流量,并強(qiáng)迫用戶(hù)等待未被緩存的內(nèi)容從網(wǎng)絡(luò)上下載回來(lái)。更多的信息可參見(jiàn)拓展閱讀中的“解讀訪問(wèn)統(tǒng)計(jì)”對(duì)應(yīng)內(nèi)容。
我該如何查看HTTP頭?
許多瀏覽器可以查看Expires
和Last-Modified
頭信息,如右鍵→查看頁(yè)面信息或類(lèi)似面板。例如,在Firefox瀏覽器下Add:
表示要看到完整的頭,您可以使用Telnet⑪客戶(hù)端手動(dòng)連接到Web服務(wù)器上。
為此,你可能需要用一個(gè)字段指定端口(默認(rèn)是80),或者連接到www.example.com:80
或者www.example.com 80
(注意是空格),更多設(shè)置請(qǐng)參考一下telnet客戶(hù)端的文檔。
一旦連接到該網(wǎng)站,輸入請(qǐng)求。比如,你想查看http://www.example.com/foo.html
的頭信息,首先連接到www.example.com
, 使用80端口,并輸入:
GET /foo.html HTTP/1.1 [return] Host: www.example.com [return][return]
[return]
等同敲回車(chē)鍵,最后輸入兩次確認(rèn)。這樣就會(huì)輸出頭信息,然后跟著實(shí)際內(nèi)容。如果只想看到頭信息,使用HEAD
來(lái)替換GET
.
⑪Telnet:Telnet協(xié)議是TCP/IP協(xié)議族中 的一員,是Internet遠(yuǎn)程登陸服務(wù)的標(biāo)準(zhǔn)協(xié)議和主要方式。它為用戶(hù)提供了在本地計(jì)算機(jī)上完成遠(yuǎn)程主機(jī)工作的能力。在終端使用者的電腦上使用 telnet程序,用它連接到服務(wù)器。終端使用者可以在telnet程序中輸入命令,這些命令會(huì)在服務(wù)器上運(yùn)行,就像直接在服務(wù)器的控制臺(tái)上輸入一樣???以在本地就能控制服務(wù)器。要開(kāi)始一個(gè)telnet會(huì)話,必須輸入用戶(hù)名和密碼來(lái)登錄服務(wù)器。Telnet是常用的遠(yuǎn)程控制Web服務(wù)器的方法。
我的頁(yè)面是密碼保護(hù)的,代理緩存是怎么處理的?
默認(rèn)情況下,HTTP驗(yàn)證保護(hù)的頁(yè)面是私有的,共享緩存是不能保存的。然而,你可以通過(guò)Cache-Control: public
頭的設(shè)置使其公有。HTTP 1.1標(biāo)準(zhǔn)兼容的緩存服務(wù)器可以使之緩存。
如果你希望這些緩存的頁(yè)面在用戶(hù)查看之前還要驗(yàn)證一下,可以組合使用Cache-Control: public
和no-cache
頭,這相對(duì)于告訴緩存器它從緩存中送出內(nèi)容前必須遞交客戶(hù)端的驗(yàn)證給原始服務(wù)器。這個(gè)頭信息如下所示:
Cache-Control: public, no-cache
不管怎么,這是最小化驗(yàn)證最好的方法;例如,你的圖片不敏感,你可以把它放在分離的目錄中,并配置你的服務(wù)對(duì)它們不做強(qiáng)制驗(yàn)證。這樣,那些圖片就會(huì)很自然的被緩存了。
如果人們通過(guò)緩存訪問(wèn)我的網(wǎng)站,我應(yīng)該擔(dān)心安全嗎?
SSL頁(yè)面不會(huì)被代理服務(wù)器緩存,所以這個(gè)你不需要擔(dān)心。但是,代理服務(wù)器就好非SSL頁(yè)面請(qǐng)求以及URL抓取這口,你懂的,這是不安全的。無(wú)良的管理員可能就會(huì)收集網(wǎng)站用戶(hù)的信息,尤其在URL中。
事實(shí)上,任何網(wǎng)絡(luò)管理員都可以收集你的客戶(hù)端和服務(wù)器端之間的這類(lèi)信息。CGI ⑫腳本有個(gè)漏洞,會(huì)把用戶(hù)名和密碼放在自身的URL地址中,這很容易讓其他人發(fā)現(xiàn)用戶(hù)的登陸信息。
如果你懂得互聯(lián)網(wǎng)安全的些基本機(jī)制,就不會(huì)對(duì)代理緩存感到任何驚訝。
⑫CGI:通用網(wǎng)關(guān)接口(Common Gateway Interface). 用于初始化軟件服務(wù)的服務(wù)器方接口。這套接口描述了Web服務(wù)器與同一計(jì)算機(jī)上的軟件的通信方式。
通用網(wǎng)關(guān)接口,它是一段程序,運(yùn)行在服務(wù)器上,提供同客戶(hù)端HTML頁(yè)面的接口,通俗的講CGI就像是一座橋,把網(wǎng)頁(yè)和WEB服務(wù)器中的執(zhí)行程序連 接起來(lái),它把HTML接收的指令傳遞給服務(wù)器,再把服務(wù)器執(zhí)行的結(jié)果返還給HTML頁(yè);用CGI可以實(shí)現(xiàn)處理表格,數(shù)據(jù)庫(kù)查詢(xún),發(fā)送電子郵件等許多操作, 最常見(jiàn)的CGI程序就是計(jì)數(shù)器。CGI使網(wǎng)頁(yè)變得不是靜態(tài)的,而是交互式的。
我在尋找一個(gè)集成的Web發(fā)布解決方案。哪些是可緩存的?
這個(gè)是不確定的。一般來(lái)說(shuō),越復(fù)雜的系統(tǒng)越難緩存。最差的情況就是所有的內(nèi)容都是動(dòng)態(tài)生成,并且不提供校驗(yàn)器,與緩存壓根無(wú)緣。你可以和你供應(yīng)商的技術(shù)人員溝通獲取更多信息,并參考下面實(shí)現(xiàn)注意事項(xiàng)。
#p#
我的圖片緩存一個(gè)月后才到期,我現(xiàn)在就想變動(dòng)!
Expires
頭是繞不過(guò)去的,除非緩存(瀏覽器或者代理)空間不足才會(huì)刪除副本,緩存副本會(huì)一直使用。
最有效的方法是修改鏈接,這樣會(huì)從源服務(wù)器獲取完整的新內(nèi)容。請(qǐng)記住,調(diào)用圖片的這個(gè)頁(yè)面也會(huì)被緩存的,正因如此,我們需要讓圖片以及其他類(lèi)似的靜態(tài)資源易緩存,而頁(yè)面呢可以隨著自身的改變(例如改變了一個(gè)圖片的URL地址Add)即時(shí)更新。
如果你想擺脫特定緩存,重載內(nèi)容,可以試試強(qiáng)制刷新(在FireFox中,shift鍵+reload按鈕等同于處理Pragma: no-cache
請(qǐng)求頭)或者讓緩存管理員使用某些接口刪除內(nèi)容。
我運(yùn)行一個(gè)Web Hosting服務(wù)。我怎樣才能讓我的用戶(hù)發(fā)布緩存友好的網(wǎng)頁(yè)?
如果你使用apahe,可以考慮允許他們使用.htaccess
文件并提供相應(yīng)的文檔。
否則你需要在每一個(gè)虛擬主機(jī)上為各種緩存屬性建立預(yù)定的區(qū)域。比如:你可以指定一個(gè)叫/cache-1m
的目錄用來(lái)放讀取后要緩存一個(gè)月的內(nèi)容,然后再建一個(gè)/no-cache
的目錄,并在頭信息中指定這么目錄中的內(nèi)容不被緩存。
不管上面你做的如何,總之最好優(yōu)先給用戶(hù)量大的客戶(hù)做緩存處理。大部分服務(wù)器節(jié)約的流量以及負(fù)載都是來(lái)自高容量的網(wǎng)站。
我明明告訴網(wǎng)頁(yè)要好好緩存,但它老是去請(qǐng)求,怎么破?
緩存服務(wù)器并不總是要求內(nèi)容要保持并重用,某些條件下,他們是不保存不重用的,所有的緩存服務(wù)器都回基于文件的大小、類(lèi)型(圖片、頁(yè)面…),或者服務(wù)器空 間的剩余來(lái)確定如何緩存。如果你的文件比較大或很熱門(mén),可能就不會(huì)被緩存。有些緩存服務(wù)器允許管理員決定哪些內(nèi)容要存儲(chǔ),有些緩存服務(wù)器允許內(nèi)容長(zhǎng)存緩存 中,所以,它們總是可用的。
實(shí)現(xiàn)需注意的:Web服務(wù)器端
一般說(shuō)來(lái),應(yīng)該選擇最新版本的Web服務(wù)器程序來(lái)部署。不僅因?yàn)樗鼈儼嗬诰彺娴墓δ?,新版本往往在性能和安全性方面都有很多的改善?/p>
Apache HTTP服務(wù)器
Apache使用可選模塊包含頭信息,頭信息Expires
和Cache-Control
一并包含。這些模塊在1.2版本以上都支持。
這些模塊需要編譯到Apache中,雖然包含,但是默認(rèn)并未開(kāi)啟。為了確定相應(yīng)模塊已經(jīng)被啟用,找到httpd⑬程序,運(yùn)行httpd -l
, 它會(huì)列出可用的模塊(注意,僅有內(nèi)部編譯的模塊列表才會(huì)顯示,在較新版本的Apache中,使用httpd -M
可以包含動(dòng)態(tài)加載的模塊N),我們需要關(guān)注的是expires模塊(expires_module
)和headers模塊(headers_module
)。
⑬httpd:httpd是Apache超文本傳輸協(xié)議(HTTP)服務(wù)器的主程序。被設(shè)計(jì)為一個(gè)獨(dú)立運(yùn)行的后臺(tái)進(jìn)程,它會(huì)建立一個(gè)處理請(qǐng)求的子進(jìn)程或線程的池。
如果這些模塊不可用,你需要聯(lián)系管理員,重新編譯以包含這些模塊。這些模塊可以通過(guò)取消配置文件中的注釋掉啟用,或者在編譯的時(shí)候增加-enable -module=expires
和-enable-module=headers
參數(shù)(apache 1.3+). 參開(kāi)Apache中的INSTALL文件。
一旦你的Apache有了相應(yīng)的模塊,你可以使用mod_expires
指定過(guò)期的時(shí)間,要么在.htaccess
文件,要么在服務(wù)器的access.conf
文件。你可以設(shè)置過(guò)期時(shí)間是從訪問(wèn)時(shí)間開(kāi)始還是文件修改時(shí)間開(kāi)始,并應(yīng)用到特定類(lèi)型文件上或設(shè)為默認(rèn)配置。查看官方該模塊文檔獲得更多信息,或者遇到問(wèn)題的時(shí)候向你身邊的apache專(zhuān)家討教。
為應(yīng)用Cache-Control
頭,你需要使用mod_headers
模塊,其允許你為資源指定任意的頭信息??蓞⒖糾od_headers官方文檔。
下面是.htaccess
文件展示了如何使用頭信息:
.htaccess文件允許Web發(fā)布者使用配置文件中的指定??梢杂绊懩夸浺约白幽夸泝?nèi)容。和你的服務(wù)器管理員溝通下,看看它們是否可用。 ### activate mod_expires ExpiresActive On ### Expire .gif's 1 month from when they're accessed ExpiresByType image/gif A2592000 ### Expire everything else 1 day from when it's last modified ### (this uses the Alternative syntax) ExpiresDefault "modification plus 1 day" ### Apply a Cache-Control header to index.htmlHeader append Cache-Control "public, must-revalidate"
注意,在有些情況下,mod_expires
會(huì)自動(dòng)計(jì)算并插入Cache-Control:max-age
頭信息。
Apache 2′s的配置和1.3類(lèi)似,更多信息可以參考2.2N的mod_expires和mod_headers文檔。
微軟IIS
微軟的IIS有一些靈活的方式可以很容易得設(shè)置頭信息,不過(guò)似乎只針對(duì)IIS 4.0服務(wù)器,并且只能在NT服務(wù)器上運(yùn)行。
為了給網(wǎng)站某區(qū)域指定頭信息,需要進(jìn)入Administration
(管理員)工具面板,然后再設(shè)置屬性。選擇HTTP Headers
選項(xiàng)卡后,你會(huì)看到兩個(gè)有意思的區(qū)域:Enable Content Expiration
和Custom HTTP headers
, 第一個(gè)含義一目了然,第二個(gè)用來(lái)應(yīng)用Cache-Control
頭。//zxx: 此處的操作描述很過(guò)時(shí)了,看看window7下,操作界面早就大變樣了!
設(shè)置ASP頁(yè)面(Active Server Pages)的頭信息可以參考后面的ASP章節(jié),也可以通過(guò)ISAPI模塊設(shè)置頭信息,細(xì)節(jié)請(qǐng)參考MSDN。
Netscape/iPlanet企業(yè)服務(wù)器
3.6版本以后,企業(yè)版服務(wù)器已經(jīng)不能以任何方式設(shè)置Expires
頭信息了。然而,其從3.0版本開(kāi)始支持HTTP 1.1的功能。這意味著HTTP 1.1的緩存(代理服務(wù)器/瀏覽器)利用你對(duì)Cache-Control
的設(shè)置來(lái)獲得。
為了使用Cache-Control
頭,在管理員服務(wù)器中選擇Content Management | Cache Control Directives
(內(nèi)容管理|緩存控制指令)。然后,使用資源選擇器(Resource Picker),選擇你希望設(shè)置頭信息的目錄。設(shè)置完頭信息后,點(diǎn)擊”確定”。更多信息請(qǐng)參考NES手冊(cè)。
實(shí)現(xiàn)需注意的:服務(wù)端腳本
時(shí)刻謹(jǐn)記,在Web服務(wù)器上設(shè)置HTTP要比通過(guò)腳本設(shè)置輕松些。你可以?xún)烧叨荚囋嚒?/p>
因?yàn)榉?wù)器端的腳本主要是為了動(dòng)態(tài)內(nèi)容,所以即使實(shí)際上內(nèi)容可以被緩存的,其也不會(huì)生成緩存很強(qiáng)的頁(yè)面。如果你的頁(yè)面內(nèi)容經(jīng)常變動(dòng),但不是每個(gè)頁(yè)面都中槍?zhuān)梢钥紤]設(shè)置Cache-Control: max-age
頭信息,大部分用戶(hù)是在相對(duì)端的時(shí)間內(nèi)再次訪問(wèn)這個(gè)頁(yè)面。例如:用戶(hù)點(diǎn)擊“后退”按鈕,如果沒(méi)有任何驗(yàn)證或新鮮度信息,他們將不得不等待,直到從服務(wù)器頁(yè)面重新下載才能看到它。
CGI
CGI腳本是生成內(nèi)容最常用的技術(shù)之一。你可以輕輕松松在請(qǐng)求發(fā)送給主體之前添加HTTP請(qǐng)求信息。大部分CGI實(shí)現(xiàn)都需要添加Content-Type
頭信息,例如這個(gè)Perl腳本://zxx: 還是挺好懂的
<#!/usr/bin/perl print "Content-type: text/htmln"; print "Expires: Thu, 29 Oct 1998 17:04:19 GMTn"; print "n"; ### the content body follows.../pre>
由于都是文本,你可以很容易通過(guò)內(nèi)置函數(shù)生成Expires
和其他日期相關(guān)的頭信息。如果你使用Cache-Control: max-age
會(huì)更簡(jiǎn)單:
print "Cache-Control: max-age=600n";
面腳本可以讓請(qǐng)求完成后緩存10分鐘,因此,當(dāng)用戶(hù)點(diǎn)擊“后退”按鈕的時(shí)候,就不會(huì)重新涂膠請(qǐng)求了。
CGI的規(guī)范同時(shí)也允許在腳本環(huán)境中,客戶(hù)端發(fā)送請(qǐng)求頭信息,每個(gè)頭信息都有一個(gè)’HTTP_’的前綴。于是乎,如果一個(gè)客戶(hù)端發(fā)送一個(gè)If-Modified-Since
請(qǐng)求,就是這樣的:
HTTP_IF_MODIFIED_SINCE
可觀摩cgi_buffer庫(kù),其可以自動(dòng)實(shí)現(xiàn)Etag
生成和驗(yàn)證,Content-Length
生成及gzip內(nèi)容,而所有這些實(shí)現(xiàn),只需要一行include,就可以為Perl和Python寫(xiě)CGI腳本。Python版本還可以包裝任意的CGI腳本。
#p#
服務(wù)器端包含
SSI(擴(kuò)展名通常是.shtml
)最早可以生成動(dòng)態(tài)內(nèi)容的網(wǎng)站發(fā)布方案。通過(guò)在頁(yè)面中使用特定的標(biāo)簽,有一定限制的內(nèi)HTML腳本就可以使用了。大部分的SSI實(shí)現(xiàn)不設(shè)置驗(yàn)證器,故無(wú)法緩存。不過(guò)Apache服務(wù)器允許通過(guò)設(shè)置讓SSI文件可緩存,通過(guò)適當(dāng)?shù)奈募⒔Y(jié)合XbitHack full
指令設(shè)置組執(zhí)行權(quán)限。欲了解更多信息,請(qǐng)參閱mod_include文檔。
PHP
PHP為服務(wù)器端腳本語(yǔ)言,在服務(wù)器內(nèi)置的時(shí)候,可以在HTML頁(yè)面中內(nèi)嵌使用,很像SSL,不過(guò)有更多的可選項(xiàng)。PHP可以在任何Web服務(wù)器(Unix或Windows)或Apache模塊上作為CGI使用。
默認(rèn)情況下,PHP生成的內(nèi)容沒(méi)有分配驗(yàn)證器,因此,不能緩存。不過(guò),開(kāi)發(fā)人員可以通過(guò)Header()
函數(shù)設(shè)置HTTP頭信息。例如,創(chuàng)建Cache-Control
頭,過(guò)期時(shí)間為3天:
記住Header()
需要在所有的輸出之前。
正如你看到的,你可以手工創(chuàng)建HTTP日期。PHP沒(méi)有專(zhuān)門(mén)的函數(shù)(新版本已改進(jìn),請(qǐng)參考PHP的日期相關(guān)函數(shù)文檔)。當(dāng)然,最簡(jiǎn)單的還是設(shè)置Cache-Control: max-age
頭信息,適用于大部分情況。
還是cgi_buffer庫(kù),只要一行包含,就能以PHP腳本形式自動(dòng)實(shí)現(xiàn)Etag
生成和驗(yàn)證,Content-Length
生成及gzip內(nèi)容。
Cold Fusion
Cold Fusion是Macromedia的商業(yè)服務(wù)器端腳本引擎,并且支持多種Windows平臺(tái),Linux平臺(tái)和多種Unix平臺(tái)。//zxx: 看到Macromedia心亮了半截,幾百年前就被收購(gòu)的公司……此文未免太過(guò)時(shí)了點(diǎn)了~~大家這段可以跳過(guò)了,幾乎沒(méi)有任何價(jià)值……
Cold Fusion通過(guò)CFHEADER標(biāo)記設(shè)置HTTP頭信息相對(duì)容易??上У氖?,以下的Expires頭信息的設(shè)置有些容易誤導(dǎo):
<CFHEADER NAME="Expires" VALUE="#Now()#">
它并不像你想像的那樣工作,因?yàn)闀r(shí)間(本例中為請(qǐng)求發(fā)起的時(shí)間)并不會(huì)被轉(zhuǎn)換成一個(gè)符合HTTP時(shí)間,而且打印出副本的Cold fusion的日期/時(shí)間對(duì)象,大部分客戶(hù)端會(huì)忽略或者將其轉(zhuǎn)換成1970年1月1日。
但是:Cold Fusion另外提供了一套日期格式化函數(shù)-GetHttpTimeSTring. 結(jié)合DateAdd函數(shù),就很容易設(shè)置過(guò)期時(shí)間了,這里我們?cè)O(shè)置一個(gè)頭信息,聲明內(nèi)容在1個(gè)月以后過(guò)期:
<cfheader name="Expires" value="#GetHttpTimeString(DateAdd('m', 1, Now()))#">
你也可以使用CFHEADER
標(biāo)簽設(shè)置Cache-Control: max-age
以及其他頭信息。
記住,Web服務(wù)器也會(huì)將頭信息設(shè)置轉(zhuǎn)給Cold Fusion(做為CGI運(yùn)行的時(shí)候),檢查你的服務(wù)器設(shè)置并確定你是否可以利用服務(wù)器設(shè)置代替Cold Fusion.
ASP和ASP.NET
在asp中設(shè)置HTTP頭信息時(shí),確保Response
方法調(diào)用在HTML內(nèi)容輸出之前,或者使用Response.Buffer
暫存輸出。同時(shí),注意某些版本的IIS默認(rèn)設(shè)置會(huì)輸出Cache-Control: private
頭信息,必須聲明成public
才能被共享緩存服務(wù)器緩存。
ASP(Active Server Pages),IIS內(nèi)置,也可用于其他Web服務(wù)器,同樣允許你設(shè)置HTTP頭。例如設(shè)置過(guò)期時(shí)間,你可以使用Response
自帶屬性:
- <% Response.Expires=1440 %>
指定內(nèi)容過(guò)期的分鐘數(shù)。Cache-Control
頭添加如下:
- <% Response.CacheControl="public" %>
在ASP.NET中,Response.Expires
已經(jīng)不推薦使用了,正確的方法是通過(guò)Response.Cache
設(shè)置緩存相關(guān)的頭信息,如下:
Response.Cache.SetExpires ( DateTime.Now.AddMinutes ( 60 ) ) ; Response.Cache.SetCacheability ( HttpCacheability.Public ) ;
參考文檔和拓展閱讀
- HTTP 1.1規(guī)范
- HTTP 1.1的規(guī)范對(duì)頁(yè)面緩存以及權(quán)威的接口實(shí)現(xiàn)指南有了大量的擴(kuò)展,參考章節(jié):13, 14.9, 14.21以及14.25 .
- Web-Caching.com
- 對(duì)緩存概念有很好的介紹,并且有很多其他在線資源的鏈接。
- 解讀訪問(wèn)統(tǒng)計(jì)
- Jeff Goldberg這篇內(nèi)容豐富敘述會(huì)告訴你為什么不應(yīng)該過(guò)度依賴(lài)訪問(wèn)統(tǒng)計(jì)和計(jì)數(shù)器。//zxx 上世紀(jì)的復(fù)古頁(yè)面…
- REDbot
- 檢查HTTP資源,以確定它們?nèi)绾闻cWeb緩存交互,以及通常如何使用該協(xié)議。
- cgi_buffer庫(kù)
- 只要包含一行Perl CGI, Python CGI以及PHP腳本,就能自動(dòng)實(shí)現(xiàn)
Etag
生成以及驗(yàn)證,Content-Length
生成以及Gzip內(nèi)容的正確編碼。Python版本還可以包裝任意的CGI腳本。
文檔說(shuō)明:
含有上標(biāo)N的表示與前輩翻譯時(shí)候相比新增的;上標(biāo)Add表示作為譯者的我為了便于理解自己添加的;上標(biāo)數(shù)字(①-⑬)是對(duì)一些可能不熟悉的名詞的百科解釋。
雖然原作語(yǔ)言不生動(dòng),教科書(shū)般一板一眼⑭;有些可能過(guò)時(shí)了。不過(guò),還是學(xué)到了很多東西。還是很值的!歡迎分享,歡迎傳播,以后面試之前來(lái)這里看看,可能會(huì)有幫助哦!
⑭ 如果我介紹緩存,我可能就這么講:緩存是什么?顧名思意,就是緩慢的存錢(qián)。為什么要緩慢的存錢(qián),因?yàn)楣べY卡都上交老婆了,為了攢點(diǎn)零花錢(qián)又不能被老婆發(fā) 現(xiàn),只能慢慢存了。那緩存有什么用呢?你想啊,自己有點(diǎn)小錢(qián),做事情就方便快捷了,比方說(shuō)我想買(mǎi)個(gè)魚(yú)竿,就不要去向老婆要(給不給先不談),自己從自己這 邊取,大大提高了執(zhí)行的速度。
那什么時(shí)候可以存什么時(shí)候不能存呢?老婆給零花錢(qián)的時(shí)候,可能會(huì)有過(guò)期時(shí)間頭,例如,周一甩了100塊錢(qián),拿去,這是一周的伙食!這個(gè)一周就是過(guò)期時(shí)間頭(Expires Header),在這個(gè)時(shí)間內(nèi),你的錢(qián)可以從緩存,也就是自己這里取……
原文鏈接:http://www.mnot.net/cache_docs/
譯文鏈接:http://www.zhangxinxu.com/wordpress/?p=3338