緩存對(duì)于web開發(fā)有重要作用,尤其是大負(fù)荷web系統(tǒng)開發(fā)中,。 緩存分很多種:服務(wù)器緩存,,第三方緩存,瀏覽器緩存等,。其中瀏覽器緩存是代價(jià)最小的,,因?yàn)闉g覽器緩存依賴的是客戶 端,而幾乎不耗費(fèi)服務(wù)器端的資源,。 讓瀏覽器做緩存需要給瀏覽器發(fā)送指定的Http頭,,告訴瀏覽器緩存多長(zhǎng)時(shí)間,或者堅(jiān)決不要緩存,。 1.Expires(過期時(shí)間)HTTP頭信息Expires(過期時(shí)間) 屬性是HTTP控制緩存的基本手段,,這個(gè)屬性告訴緩存器:相關(guān)副本在多長(zhǎng)時(shí)間內(nèi)是新鮮的。過了這個(gè)時(shí)間,,緩存器就會(huì)向源服務(wù)器發(fā)送請(qǐng)求,,檢查文檔是否被修 改。幾乎所有的緩存服務(wù)器都支持Expires(過期時(shí)間)屬性,; 大部分Web服務(wù)器支持你用幾種方式設(shè)置Expires屬性,;一般 的:可以設(shè)計(jì)一個(gè)絕對(duì)時(shí)間間隔:基于客戶最后查看副本的時(shí)間(最后訪問時(shí)間)或者根據(jù)服務(wù)器上文檔最后被修改的時(shí)間,; Expires 頭信息:對(duì)于設(shè)置靜態(tài)圖片文件(例如導(dǎo)航欄和圖片按鈕)可緩存特別有用;因?yàn)檫@些圖片修改很少,,你可以給它們?cè)O(shè)置一個(gè)特別長(zhǎng)的過期時(shí)間,,這會(huì)使你的網(wǎng)站對(duì) 用戶變得相應(yīng)非常快,;他們對(duì)于控制有規(guī)律改變的網(wǎng)頁(yè)也很有用,,例如:你每天早上6點(diǎn)更新新聞頁(yè),你可以設(shè)置副本的過期時(shí)間也是這個(gè)時(shí)間,,這樣緩存 服務(wù)器就知道什么時(shí)候去取一個(gè)更新版本,,而不必讓用戶去按瀏覽器的“刷新”按鈕。 過期時(shí)間頭信息屬性值只能是HTTP格式的日期時(shí)間,,其他的都會(huì)被解析成當(dāng)前時(shí)間“之前”,,副本會(huì)過期,記?。篐TTP的日期時(shí)間必須是格林威治時(shí) 間(GMT),,而不是本地時(shí)間。舉例: 所以使用過期時(shí)間屬性一定要確認(rèn)你的Web服務(wù)器時(shí)間設(shè)置正確,,一個(gè)途徑是通過網(wǎng)絡(luò)時(shí)間同步協(xié)議(Network Time Protocol NTP),,和你的系統(tǒng)管理員那里你可以了解更多細(xì)節(jié)。 雖然過期時(shí)間屬性非常有用,,但是它還是有些局限,首先:是牽扯到了日期,,這樣Web服務(wù)器的時(shí)間和緩存服務(wù)器的時(shí)間必須是同步的,,如果有些不同步, 要么是應(yīng)該緩存的內(nèi)容提前過期了,,要么是過期結(jié)果沒及時(shí)更新,。 還有一個(gè)過期時(shí)間設(shè)置的問題也不容忽視:如果你設(shè)置的過期時(shí)間是一個(gè)固定的時(shí)間,如果你返回內(nèi)容的時(shí)候又沒有連帶更新下次過期的時(shí)間,,那么之后所有 訪問請(qǐng)求都會(huì)被發(fā)送給源Web服務(wù)器,,反而增加了負(fù)載和響應(yīng)時(shí)間; 2.Cache-Control(緩存控制) HTTP頭信息HTTP 1.1介紹了另外一組頭信息屬性:Cache-Control響應(yīng)頭信息,,讓網(wǎng)站的發(fā)布者可以更全面的控制他們的內(nèi)容,,并定位過期時(shí)間的限制。 max-age=[秒] — 執(zhí)行緩存被認(rèn)為是最新的最長(zhǎng)時(shí)間,。類似于過期時(shí)間,,這個(gè)參數(shù)是基于請(qǐng)求時(shí)間的相對(duì)時(shí)間間隔,而不是絕對(duì)過期時(shí)間,,[秒]是一個(gè)數(shù)字,,單位是秒:從請(qǐng)求時(shí)間 開始到過期時(shí)間之間的秒數(shù),。 給靜態(tài)資源(HTML文件,,圖片文件等)的Repsone加上Expires/Cache-Control Header是很有效的一招。如果HTTP Response中有Expires這樣的Header的話,,瀏覽器會(huì)Cache這個(gè)資源,,理想狀況下(注意,只是理想狀況),,在Expire Date之前,,不會(huì)再發(fā)HTTP請(qǐng)求給Server要這個(gè)資源,不過Expires的值只能是一個(gè)固定日期,,比如“Thu 27 Nov 2008 07:00:00 GMT”,,不能是一個(gè)類似“從現(xiàn)在開始之后10年”這樣一個(gè)隨機(jī)浮動(dòng)的值,如果要這樣的效果,,可以用Cache-Control這樣的Header,,如果 HTTP Response中有這樣的Header:“Cache-Control: max-age = 100”,表示這個(gè)資源在cache中的最大壽命是100秒,。一般說來這種靜態(tài)文件永遠(yuǎn)不應(yīng)該過期,,如果真的要給這個(gè)Cache加上一個(gè)期限,那我希望是 ——一萬年,,“Cache-Control: max-age = 315360000000” 其實(shí)就應(yīng)該給Expires設(shè)一個(gè)永遠(yuǎn)不會(huì)過期的時(shí)間,,比如你現(xiàn)在有一個(gè)文件叫l(wèi)ogo.gif,需要用一個(gè)新的logo的時(shí)候,,你不要去 覆蓋原來的文件,,而把新的logo存成logo_v2.gif,讓相關(guān)網(wǎng)頁(yè)引用新的logo_v2.gif,,這樣可以讓新老網(wǎng)頁(yè)同時(shí)工作,,實(shí)在犯不上為了 節(jié)省存儲(chǔ)空間覆蓋原有文件,。 對(duì)Apache服務(wù)器,使用mod_expires,,在httpd.conf或者.htaccess中加上 <FilesMatch “\\.(ico|gif|jpg|html)$”>ExpiresDefault “access plus 10 years”</FileMatch> 3.Last-Modified/If-Modified-Since有些數(shù)據(jù)隨時(shí)都在變化,。 CNN.com 的主頁(yè)經(jīng)常幾分鐘就更新。另一方面,,Google.com 的主頁(yè)幾個(gè)星期才更新一次 (當(dāng)他們上傳特殊的假日 logo,,或?yàn)橐粋€(gè)新服務(wù)作廣告時(shí))。 Web 服務(wù)是不變的:通常服務(wù)器知道你所請(qǐng)求的數(shù)據(jù)的最后修改時(shí)間,,并且 HTTP 為服務(wù)器提供了一種將最近修改數(shù)據(jù)連同你請(qǐng)求的數(shù)據(jù)一同發(fā)送的方法,。 如果你第二次 (或第三次,或第四次) 請(qǐng)求相同的數(shù)據(jù),,你可以告訴服務(wù)器你上一次獲得的最后修改日期:在你的請(qǐng)求中發(fā)送一個(gè) If-Modified-Since 頭信息,,它包含了上一次從服務(wù)器連同數(shù)據(jù)所獲得的日期。如果數(shù)據(jù)從那時(shí)起沒有改變,,服務(wù)器將返回一個(gè)特殊的 HTTP 狀態(tài)代碼 304,,這意味著 “從上一次請(qǐng)求后這個(gè)數(shù)據(jù)沒有改變”。這一點(diǎn)有何進(jìn)步呢,?當(dāng)服務(wù)器發(fā)送狀態(tài)編碼 304 時(shí),,不再重新發(fā)送數(shù)據(jù)。您僅僅獲得了這個(gè)狀態(tài)代碼,。所以當(dāng)數(shù)據(jù)沒有更新時(shí),,你不需要一次又一次地下載相同的數(shù)據(jù);服務(wù)器假定你有本地的緩存數(shù)據(jù),。 所有現(xiàn)代的瀏覽器都支持最近修改 (last-modified) 的數(shù)據(jù)檢查,。如果你曾經(jīng)訪問過某頁(yè),一天后重新訪問相同的頁(yè)時(shí)發(fā)現(xiàn)它沒有變化,,并奇怪第二次訪問時(shí)頁(yè)面加載得如此之快——這就是原因所在。你的瀏覽器首次 訪問時(shí)會(huì)在本地緩存頁(yè)面內(nèi)容,,當(dāng)你第二次訪問,,瀏覽器自動(dòng)發(fā)送首次訪問時(shí)從服務(wù)器獲得的最近修改日期。服務(wù)器簡(jiǎn)單地返回 304: Not Modified (沒有修改),,因此瀏覽器就會(huì)知道從本地緩存加載頁(yè)面,。在這一點(diǎn)上,Web 服務(wù)也如此智能,。 4. ETag/If-None-MatchETag 是實(shí)現(xiàn)與最近修改數(shù)據(jù)檢查同樣的功能的另一種方法:沒有變化時(shí)不重新下載數(shù)據(jù),。其工作方式是:服務(wù)器發(fā)送你所請(qǐng)求的數(shù)據(jù)的同時(shí),發(fā)送某種數(shù)據(jù)的 hash (在 ETag 頭信息中給出),。hash 的確定完全取決于服務(wù)器,。當(dāng)?shù)诙握?qǐng)求相同的數(shù)據(jù)時(shí),,你需要在 If-None-Match: 頭信息中包含 ETag hash,如果數(shù)據(jù)沒有改變,,服務(wù)器將返回 304 狀態(tài)代碼,。與最近修改數(shù)據(jù)檢查相同,服務(wù)器僅僅 發(fā)送 304 狀態(tài)代碼,;第二次將不為你發(fā)送相同的數(shù)據(jù),。在第二次請(qǐng)求時(shí),通過包含 ETag hash,,你告訴服務(wù)器:如果 hash 仍舊匹配就沒有必要重新發(fā)送相同的數(shù)據(jù),,因?yàn)槟氵€有上一次訪問過的數(shù)據(jù)。 這幾個(gè)http頭可以作為meta標(biāo)簽發(fā)送到客戶端,,但是需要注意的是Http頭中的設(shè)置優(yōu)先級(jí)更高一些,,例如: 總結(jié)Expires/Cache-Control Header是控制瀏覽器是否直接從瀏覽器緩存取數(shù)據(jù)還是重新發(fā)請(qǐng)求到服務(wù)器取數(shù)據(jù)。只是Cache-Control比Expires可以控制的多一些,, 而且Cache-Control會(huì)重寫Expires的規(guī)則,。 Last-Modified/If-Modified-Since和ETag/If-None-Match是瀏覽器發(fā)送請(qǐng)求到服務(wù)器后判斷文件是否 已經(jīng)修改過,如果沒有修改過就只發(fā)送一個(gè)304回給瀏覽器,,告訴瀏覽器直接從自己本地的緩存取數(shù)據(jù),;如果修改過那就整個(gè)數(shù)據(jù)重新發(fā)給瀏覽器。 |
|