天天看點

面向站長和網站管理者的Web緩存加速指南[翻譯]

<a href="http://www.chedong.com/tech/cache_docs.html">http://www.chedong.com/tech/cache_docs.html</a>

這是一篇知識性的文檔,主要目的是為了讓Web緩存相關概念更容易被開發者了解并應用于實際的應用環境中。為了簡要起見,某些實作方面的細節被簡化或省略了。如果你更關心細節實作則完全不必耐心看完本文,後面參考文檔和更多深入閱讀部分可能是你更需要的内容。

什麼是Web緩存,為什麼要使用它?

緩存的類型:

浏覽器緩存;

代理伺服器緩存;

Web緩存無害嗎?為什麼要鼓勵緩存?

Web緩存如何工作:

如何控制(控制不)緩存:

HTML Meta标簽 vs. HTTP頭資訊;

Pragma HTTP頭資訊(為什麼不起作用);

使用Expires(過期時間)HTTP頭資訊控制保鮮期;

Cache-Control(緩存控制) HTTP頭資訊;

校驗參數和校驗;

建立利于緩存網站的竅門;

編寫利于緩存的腳本;

常見問題解答;

緩存機制的實作:Web伺服器端配置;

緩存機制的實作:伺服器端腳本;

參考文檔和深入閱讀;

關于本文檔;

Web緩存位于Web伺服器之間(1個或多個,内容源伺服器)和用戶端之間(1個或多個):緩存會根據進來的請求儲存輸出内容的副本,例如html頁面, 圖檔,檔案(統稱為副本),然後,當下一個請求來到的時候:如果是相同的URL,緩存直接使用副本響應通路請求,而不是向源伺服器再次發送請求。

使用緩存主要有2大理由:

減少相應延遲:因為請求從緩存伺服器(離用戶端更近)而不是源伺服器被相應,這個過程耗時更少,讓web伺服器看上去相應更快;

減少網絡帶寬消耗:當副本被重用時會減低用戶端的帶寬消耗;客戶可以節省帶寬費用,控制帶寬的需求的增長并更易于管理。

對于新一代的Web浏覽器來說(例如:IE,Firefox):一般都能在設定對話框中發現關于緩存的設定,通過在你的電腦上僻處一塊硬碟空間用于存儲你已經看過的網站的副本。浏覽器緩存根據非常簡單的規則進行工作:在同一個會話過程中(在目前浏覽器沒有被關閉之前)會檢查一次并确定緩存的副本足夠新。這個緩存對于使用者點選“後退”或者點選剛通路過的連結特别有用,如果你浏覽過程中通路到同一個圖檔,這些圖檔可以從浏覽器緩存中調出而即時顯現。

Web代理伺服器使用同樣的緩存原理,隻是規模更大。代理伺服器群為成百上千使用者服務使用同樣的機制;大公司和ISP經常在他們的防火牆上架設代理緩存或者單獨的緩存裝置;

由于帶路伺服器緩存并非用戶端或者源伺服器的一部分,而是位于原網絡之外,請求必須路由到他們才能起作用。一個方法是手工設定你的浏覽器:告訴浏覽器使用 那個代理,另外一個是通過中間伺服器:這個中間伺服器處理所有的web請求,并将請求轉發到背景網絡,而使用者不必配置代理,甚至不必知道代理的存在;

代理伺服器緩存:是一個共享緩存,不隻為一個使用者服務,經常為大量使用者使用,是以在減少相應時間和帶寬使用方面很有效:因為同一個副本會被重用多次。

也被稱為反向代理緩存或間接代理緩存,網關緩存也是一個中間伺服器,和内網管理者部署緩存用于節省帶寬不同:網關緩存一般是網站管理者自己部署:讓他們的網站更容易擴充并獲得更好的性能;

請求有幾種方法被路由到網關緩存伺服器上:其中典型的是讓用一台或多台負載均衡伺服器從用戶端看上去是源伺服器;

本問主要關注于浏覽器和代理緩存,當然,有些資訊對于網關緩存也同樣有效;

Web緩存在網際網路上最容易被誤解的技術之一:網站管理者經常怕對網站失去控制,由于代理緩存會“隐藏”他們的使用者,讓他們感覺難以監控誰在使用他們的網站。

不幸的是:就算不考慮Web緩存,網際網路上也有很多網站使用非常多的參數以便管理者精确地跟蹤使用者如何使用他們的網站;如果這類問題也是你關心的,本文将告訴你如何獲得精确的統計而不必将網站設計的非常緩存不友好。

另外一個抱怨是緩存會給使用者過期或失效的資料;無論如何:本文可以告訴你怎樣配置你的伺服器來控制你的内容将被如何緩存。

CDN是另外一個有趣的方向,和其他代理緩存不同:CDN的網關緩存為希望被緩存的網站服務,沒有以上顧慮。即使你使用了CDN,你也要考慮後續的代理伺服器緩存和浏覽器緩存問題。

另外一方面:如果良好地規劃了你的網站,緩存會有助于網站服務更快,并節省伺服器負載和網際網路的連結請求。這個改善是顯著的:一個難以緩存的網站可能需要幾秒去載入頁面,而對比有緩存的網站頁面幾乎是即時顯現:使用者更喜歡速度快的網站并更經常的通路;

這樣想:很多大型網際網路公司為全世界伺服器群投入上百萬資金,為的就是讓使用者通路盡可能快,用戶端緩存也是這個目的,隻不過更靠近使用者一端,而且最好的一點是你甚至根本不用為此付費。

事實上,無論你是否喜歡,代理伺服器和浏覽器都回啟用緩存。如果你沒有配置網站正确的緩存,他們會按照預設或者緩存管理者的政策進行緩存。

所有的緩存都用一套規則來幫助他們決定什麼時候使用緩存中的副本提供服務(假設有副本可用的情況下);一些規則在協定中有定義(HTTP協定1.0和1.1),一些規則由緩存的管理者設定(浏覽器的使用者或者代理伺服器的管理者);

一般說來:遵循以下基本的規則(不必擔心,你不必知道所有的細節,細節将随後說明)

如果響應頭資訊:告訴緩存器不要保留緩存,緩存器就不會緩存相應内容;

如果請求資訊是需要認證或者安全加密的,相應内容也不會被緩存;

如果在回應中不存在校驗器(ETag或者Last-Modified頭資訊),緩存伺服器會認為缺乏直接的更新度資訊,内容将會被認為不可緩存。

一個緩存的副本如果含有以下資訊:内容将會被認為是足夠新的

含有完整的過期時間和壽命控制頭資訊,并且内容仍在保鮮期内;

浏覽器已經使用過緩存副本,并且在一個會話中已經檢查過内容的新鮮度;

緩存代理伺服器近期内已經使用過緩存副本,并且内容的最後更新時間在上次使用期之前;

夠新的副本将直接從緩存中送出,而不會向源伺服器發送請求;

如果緩存的副本已經太舊了,緩存伺服器将向源伺服器送出請求校驗請求,用于确定是否可以繼續使用目前拷貝繼續服務;

總之:新鮮度和校驗是确定内容是否可用的最重要途徑:

如果副本足夠新,從緩存中提取就立刻能用了;

而經緩存器校驗後發現副本的原件沒有變化,系統也會避免将副本内容從源伺服器整個重新傳輸一遍。

有很多工具可以幫助設計師和網站管理者調整緩存伺服器對待網站的方式,這也許需要你親自下手對伺服器的配置進行一些調整,但絕對值得;了解如何使用這些工具請參考後面的實作章節;

HTML的編寫者會在文檔的&lt;HEAD&gt;區域中加入描述文檔的各種屬性,這些META标簽常常被用于标記文檔不可以被緩存或者标記多長時間後過期;

META标簽使用很簡單:但是效率并不高,因為隻有幾種浏覽器會遵循這個标記(那些真正會“讀懂”HTML的浏覽器),沒有一種緩存代理伺服器能遵循這個 規則(因為它們幾乎完全不解析文檔中HTML内容);有事會在Web頁面中增加:Pragma: no-cache這個META标記,如果要讓頁面保持重新整理,這個标簽其實完全沒有必要。

如果你的網站托管在ISP機房中,并且機房可能不給你權限去控制HTTP的頭資訊(如:Expires和Cache-Control),大聲控訴:這些機制對于你的工作來說是必須的;

另外一方面: HTTP頭資訊可以讓你對浏覽器和代理伺服器如何處理你的副本進行更多的控制。他們在HTML代碼中是看不見的,一般由Web伺服器自動生成。但是,根據 你使用的服務,你可以在某種程度上進行控制。在下文中:你将看到一些有趣的HTTP頭資訊,和如何在你的站點上應用部署這些特性。

HTTP頭資訊發送在HTML代碼之前,隻有被浏覽器和一些中間緩存能看到,一個典型的HTTP 1.1協定傳回的頭資訊看上去像這樣:

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代碼的輸出,關于如何設定HTTP頭資訊請參考實作章節;

很多人認為在HTTP頭資訊中設定了Pragma: no-cache後會讓内容無法被緩存。但事實并非如此:HTTP的規範中,響應型頭資訊沒有任何關于Pragma屬性的說明,而讨論了的是請求型頭資訊 Pragma屬性(頭資訊也由浏覽器發送給伺服器),雖然少數集中緩存伺服器會遵循這個頭資訊,但大部分不會。用了Pragma也不起什麼作用,要用就使 用下列頭資訊:

Expires(過期時間) 屬性是HTTP控制緩存的基本手段,這個屬性告訴緩存器:相關副本在多長時間内是新鮮的。過了這個時間,緩存器就會向源伺服器發送請求,檢查文檔是否被修改。幾乎所有的緩存伺服器都支援Expires(過期時間)屬性;

大部分Web伺服器支援你用幾種方式設定Expires屬性;一般的:可以設計一個絕對時間間隔:基于客戶最後檢視副本的時間(最後通路時間)或者根據伺服器上文檔最後被修改的時間;

Expires頭資訊:對于設定靜态圖檔檔案(例如導航欄和圖檔按鈕)可緩存特别有用;因為這些圖檔修改很少,你可以給它們設定一個特别長的過期時間,這會使你的網站對使用者變得相應非常快;他們對于控制有規律改變的網頁也很有用,例如:你每天早上6點更新新聞頁,你可以設定副本的過期時間也是這個時間,這樣緩存 伺服器就知道什麼時候去取一個更新版本,而不必讓使用者去按浏覽器的“重新整理”按鈕。

過期時間頭資訊屬性值隻能是HTTP格式的日期時間,其他的都會被解析成目前時間“之前”,副本會過期,記住:HTTP的日期時間必須是格林威治時間(GMT),而不是本地時間。舉例:

是以使用過期時間屬性一定要确認你的Web伺服器時間設定正确,一個途徑是通過網絡時間同步協定(Network Time Protocol NTP),和你的系統管理者那裡你可以了解更多細節。

雖然過期時間屬性非常有用,但是它還是有些局限,首先:是牽扯到了日期,這樣Web伺服器的時間和緩存伺服器的時間必須是同步的,如果有些不同步,要麼是應該緩存的内容提前過期了,要麼是過期結果沒及時更新。

還有一個過期時間設定的問題也不容忽視:如果你設定的過期時間是一個固定的時間,如果你傳回内容的時候又沒有連帶更新下次過期的時間,那麼之後所有通路請求都會被發送給源Web伺服器,反而增加了負載和響應時間;

HTTP 1.1介紹了另外一組頭資訊屬性:Cache-Control響應頭資訊,讓網站的釋出者可以更全面的控制他們的内容,并定位過期時間的限制。

有用的 Cache-Control響應頭資訊包括:

max-age=[秒] — 執行緩存被認為是最新的最長時間。類似于過期時間,這個參數是基于請求時間的相對時間間隔,而不是絕對過期時間,[秒]是一個數字,機關是秒:從請求時間開始到過期時間之間的秒數。

s-maxage=[秒] — 類似于max-age屬性,除了他應用于共享(如:代理伺服器)緩存

public — 标記認證内容也可以被緩存,一般來說: 經過HTTP認證才能通路的内容,輸出是自動不可以緩存的;

no-cache — 強制每次請求直接發送給源伺服器,而不經過本地緩存版本的校驗。這對于需要确認認證應用很有用(可以和public結合使用),或者嚴格要求使用最新資料的應用(不惜犧牲使用緩存的所有好處);

no-store — 強制緩存在任何情況下都不要保留任何副本

must-revalidate — 告訴緩存必須遵循所有你給予副本的新鮮度的,HTTP允許緩存在某些特定情況下傳回過期資料,指定了這個屬性,你高速緩存,你希望嚴格的遵循你的規則。

proxy-revalidate — 和 must-revalidate類似,除了他隻對緩存代理伺服器起作用

舉例:

如果你計劃試用Cache-Control屬性,你應該看一下這篇HTTP文檔,詳見參考和深入閱讀;

在Web緩存如何工作: 我們說過:校驗是當副本已經修改後,伺服器和緩存之間的通訊機制;使用這個機制:緩存伺服器可以避免副本實際上仍然足夠新的情況下重複下載下傳整個原件。

校驗參數非常重要,如果1個不存在,并且沒有任何資訊說明保鮮期(Expires或Cache-Control)的情況下,緩存将不會存儲任何副本;

最常見的校驗參數是文檔的最後修改時間,通過最後Last-Modified頭資訊可以,當一份緩存包含Last-Modified資訊,他基于此資訊,通過添加一個If-Modified-Since請求參數,向伺服器查詢:這個副本從上次檢視後是否被修改了。

HTTP 1.1介紹了另外一個校驗參數: ETag,伺服器是伺服器生成的唯一辨別符ETag,每次副本的标簽都會變化。由于伺服器控制了ETag如何生成,緩存伺服器可以通過If-None-Match請求的傳回沒變則目前副本和原件完全一緻。

所有的緩存伺服器都使用Last-Modified時間來确定副本是否夠新,而ETag校驗正變得越來越流行;

所有新一代的Web伺服器都對靜态内容(如:檔案)自動生成ETag和Last-Modified頭資訊,而你不必做任何設定。但是,伺服器對于動态内容(例如:CGI,ASP或資料庫生成的網站)并不知道如何生成這些資訊,參考一下編寫利于緩存的腳本章節;

除了使用新鮮度資訊和校驗,你還有很多方法使你的網站緩存友好。

保持URL穩定: 這是緩存的金科玉律,如果你給在不同的頁面上,給不同使用者或者從不同的站點上提供相同的内容,應該使用相同的URL,這是使你的網站緩存友好最簡單,也是 最高效的方法。例如:如果你在頁面上使用 "/index.html" 做為引用,那麼就一直用這個位址;

使用一個共用的庫存放每頁都引用的圖檔和其他頁面元素;

對于不經常改變的圖檔/頁面啟用緩存,并使用Cache-Control: max-age屬性設定一個較長的過期時間;

對于定期更新的内容設定一個緩存伺服器可識别的max-age屬性或過期時間;

如果資料源(特别是下載下傳檔案)變更,修改名稱,這樣:你可以讓其很長時間不過期,并且保證服務的是正确的版本;而連結到下載下傳檔案的頁面是一個需要設定較短過期時間的頁面。

萬不得已不要改變檔案,否則你會提供一個非常新的Last-Modified日期;例如:當你更新了網站,不要複制整個網站的所有檔案,隻上傳你修改的檔案。

隻在必要的時候使用Cookie,cookie是非常難被緩存的,而且在大多數情況下是不必要的,如果使用cookie,控制在動态網頁上;

減少試用SSL,加密的頁面不會被任何共享緩存伺服器緩存,隻在必要的時候使用,并且在SSL頁面上減少圖檔的使用;

使用可緩存性評估引擎,這對于你實踐本文的很多概念都很有幫助;

腳本預設不會傳回校驗參數(傳回Last-Modified或ETag頭資訊)或其他新鮮度資訊(Expires或Cache-Control),有些動态腳本的确是動态内容(每次相應内容都不一樣),但是更多(搜尋引擎,資料庫引擎網站)網站還是能從緩存友好中獲益的。

一般說來,如果腳本生成的輸出在未來一段時間(幾分鐘或者幾天)都是可重複複制的,那麼就是可緩存的。如果腳本輸出内容隻随URL變化而變化,也是可緩存的;但如果輸出會根據cookie,認證資訊或者其他外部條件變化,則還是不可緩存的。

最利于緩存的腳本就是将内容改變時導出成靜态檔案,Web伺服器可以将其當作另外一個網頁并生成和試用校驗參數,讓一些都變得更簡單,隻需要寫入檔案即可,這樣最後修改時間也有了;

另外一個讓腳本可緩存的方法是對一段時間内能保持較新的内容設定一個相對壽命的頭資訊,雖然通過Expires頭資訊也可以實作,但更容易的是用Cache-Control: max-age屬性,它會讓首次請求後一段時間内緩存保持新鮮;

如果以上做法你都做不到,你可以讓腳本生成一個校驗屬性,并對 If-Modified-Since 和/或If-None-Match請求作出反應,這些屬性可以從解析HTTP頭資訊得到,并對符合條件的内容傳回304 Not Modified(内容未改變),可惜的是,這種做法比不上前2種高效;

其他竅門:

盡量避免使用POST,除非萬不得已,POST模式的傳回内容不會被大部分緩存伺服器儲存,如果你發送内容通過URL和查詢(通過GET模式)的内容可以緩存下來供以後使用;

不要在URL中加入針對每個使用者的識别資訊:除非内容是針對每個使用者不同的;

不要統計一個使用者來自一個位址的所有請求,因為緩存常常是一起工作的;

生成并傳回Content-Length頭資訊,如果友善的話,這個屬性讓你的腳本在可持續連結模式時:用戶端可以通過一個TCP/IP連結同時請求多個副本,而不是為每次請求單獨建立連結,這樣你的網站相應會快很多;

具體定義請參考實作章節。

好的政策是确定那些内容最熱門,大量的複制(特别是圖檔)并針對這些内容先部署緩存。

緩存最好的副本是那些可以長時間保持新鮮的内容;基于校驗雖然有助于加快相應,但是它不得不和源伺服器聯系一次去檢查内容是否夠新,如果緩存伺服器上就知道内容是新的,内容就可以直接相應傳回了。

如果你必須知道每次頁面通路的,選擇【一】個頁面上的小元素,或者頁面本身,通過适當的頭資訊讓其不可緩存,例如: 可以在每個頁面上部署一個1x1像素的透明圖檔。Referer頭資訊會有包含這個圖檔的每個頁面資訊;

明确一點:這個并不會給你一個關于你使用者精确度很高的統計,而且這對網際網路和你的使用者這都不太好,消耗了額外的帶寬,強迫使用者去通路無法緩存的内容。了解更多資訊,參考通路統計資料。

很多浏覽器在頁面屬性或類似界面中可以讓你看到Expires 和Last-Modified資訊;如果有的話:你會找到頁面資訊的菜單和頁面相關的檔案(如圖檔),并且包含他們的詳細資訊;

看到完整的頭資訊,你可以用telnet手工連接配接到Web伺服器;

為此:你可能需要用一個字段指定端口(預設是80),或者連結到www.example.com:80 或者 www.example.com 80(注意是空格),更多設定請參考一下telnet用戶端的文檔;

打開網站連結:請求一個檢視連結,如果你想看到http://www.example.com/foo.html 連接配接到www.example.com的80端口後,鍵入:

GET /foo.html HTTP/1.1 [回車]

GET /foo.html HTTP/1.1 [return]

Host: www.example.com [回車][回車]

Host: www.example.com [return][return]

在[回車]處按鍵盤的Enter鍵;在最後,要按2次回車,然後,就會輸出頭資訊及完整頁面,如果隻想看頭資訊,将GET換成HEAD。

預設的,網頁被HTTP認證保護的都是私密内容,它們不會被任何共享緩存保留。但是,你可以通過設定Cache-Control: public讓認證頁面可緩存,HTTP 1.1标準相容的緩存伺服器會認出它們可緩存。

如果你認為這些可緩存的頁面,但是需要每個使用者認證後才能看,可以組合使用Cache-Control: public和no-cache頭資訊,高速緩存必須在提供副本之前,将将新客戶的認證資訊送出給源伺服器。設定就是這樣:

Cache-Control: public, no-cache

無論如何:這是減少認證請求的最好方法,例如: 你的圖檔是不機密的,将它們部署在另外一個目錄,并對此配置伺服器不強制認證。這樣,那些圖檔會預設都緩存。

代理伺服器上SSL頁面不會被緩存(不推薦被緩存),是以你不必為此擔心。但是,由于緩存儲存了非SSL請求和從他們抓取的URL,你要意識到沒有安全保護的網站,可能被不道德的管理者可能搜集使用者隐私,特别是通過URL。

實際上,位于伺服器和用戶端之間的管理者可以搜集這類資訊。特别是通過CGI腳本在通過URL傳遞使用者名和密碼的時候會有很大問題;這對洩露使用者名和密碼是一個很大的漏洞;

如果你初步懂得網際網路的安全機制,你不會對緩存伺服器有任何。

這很難說,一般說來系統越複雜越難緩存。最差就是全動态釋出并不提供校驗參數;你無發緩存任何内容。可以向系統提供商的技術人員了解一下,并參考後面的實作說明。

過期時間是繞不過去的,除非緩存(浏覽器或者代理伺服器)空間不足才會删除副本,緩存副本在過期之間會被一直使用。

最好的辦法是改變它們的連結,這樣,新的副本将會從源伺服器上重新下載下傳。記住:引用它們的頁面本身也會被緩存。是以,使用靜态圖檔和類似内容是很容易緩存的,而引用他們的HTML頁面則要保持非常更新;

如果你希望對指定的緩存伺服器重新載入一個副本,你可以強制使用“重新整理”(在FireFox中在reload的時候按住shift鍵:就會有前面提到惡Pragma: no-cache頭資訊發出)。或者你可以讓緩存的管理者從他們的界面中删除相應内容;

如果你使用apahe,可以考慮允許他們使用.htaccess檔案并提供相應的文檔;

另外一方面: 你也可以考慮在各種虛拟主機上建立各種緩存政策。例如: 你可以設定一個目錄 /cache-1m 專門用于存放通路1個月的通路,另外一個 /no-cache目錄則被用提供不可存儲副本的服務。

無論如何:對于大量使用者通路還是應該用緩存。對于大網站,這方面的節約很明顯(帶寬和伺服器負載);

緩存伺服器并不會總儲存副本并重用副本;他們隻是在特定情況下會不儲存并使用副本。所有的緩存伺服器都回基于檔案的大小,類型(例如:圖檔 頁面),或者伺服器空間的剩餘來确定如何緩存。你的頁面相比更熱門或者更大的檔案相比,并不值得緩存。

是以有些緩存伺服器允許管理者根據檔案類型确定緩存副本的優先級,允許某些副本被永久緩存并長期有效;

一般說來,應該選擇最新版本的Web伺服器程式來部署。不僅因為它們包含更多利于緩存的功能,新版本往往在性能和安全性方面都有很多的改善。

Apache有些可選的子產品來包含這些頭資訊: 包括Expires和Cache-Control。 這些子產品在1.2版本以上都支援;

這些子產品需要和apache一起編譯;雖然他們已經包含在釋出版本中,但預設并沒有啟用。為了确定相應子產品已經被啟用:找到httpd程式并運作httpd -l 它會列出可用的子產品,我們需要用的子產品是mod_expires和mod_headers

如果這些子產品不可用,你需要聯系管理者,重新編譯并包含這些子產品。這些子產品有時候通過配置檔案中把注釋掉的配置啟用,或者在編譯的時候增加-enable -module=expires和-enable-module=headers選項(在apache 1.3和以上版本)。 參考Apache釋出版中的INSTALL檔案;

這裡有個例子說明如何使用頭資訊:

.htaccess檔案允許web釋出者使用指令隻在配置檔案中用到的指令。他影響到所在目錄及其子目錄;問一下你的伺服器管理者确認這個功能是否啟用了。

### 啟用 mod_expires

ExpiresActive On

### 設定 .gif 在被通路過後1個月過期。

ExpiresByType image/gif A2592000

### 其他檔案設定為最後修改時間1天後過期

### (用了另外的文法)

ExpiresDefault "modification plus 1 day"

### 在index.html檔案應用 Cache-Control頭屬性

&lt;Files index.html&gt;

Header append Cache-Control "public, must-revalidate"

&lt;/Files&gt;       

注意: 在适當情況下mod_expires會自動計算并插入Cache-Control:max-age 頭資訊

Microsoft的IIS可以非常容易的設定頭資訊,注意:這隻針對IIS 4.0伺服器,并且隻能在NT伺服器上運作。

為網站的一個區域設定頭資訊,先要到管理者工具界面中,然後設定屬性。選擇HTTP Header選單,你會看到2個有趣的區域:啟用内容過期和定制HTTP頭資訊。頭一個設定會自動配置,第二個可以用于設定Cache-Control頭資訊;

設定asp頁面的頭資訊可以參考後面的ASP章節,也可以通過ISAPI子產品設定頭資訊,細節請參考MSDN。

3.6版本以後,Netscape/iPlanet已經不能設定Expires頭資訊了,他從3.0版本開始支援HTTP 1.1的功能。這意味着HTTP 1.1的緩存(代理伺服器/浏覽器)優勢都可以通過你對Cache-Control設定來獲得。

需要注意的一點是:也許伺服器設定HTTP頭資訊比腳本語言更容易,但是兩者你都應該使用。

因為伺服器端的腳本主要是為了動态内容,他本身不産生可緩存的檔案頁面,即使内容實際是可以緩存的。如果你的内容經常改變,但是不是每次頁面請求都改變, 考慮設定一個Cache-Control: max-age頭資訊;大部分使用者會在短時間内多次通路同一頁面。例如: 使用者點選“後退”按鈕,即使沒有新内容,他們仍然要再次從伺服器下載下傳内容檢視。

CGI腳本是生成内容最流行的方式之一,你可以很容易在發送内容之前的擴充HTTP頭資訊;大部分CGI實作都需要你寫 Content-Type頭資訊,例如這個Perl腳本:

#!/usr/bin/perl

print "Content-type: text/html/n";

print "Expires: Thu, 29 Oct 1998 17:04:19 GMT/n";

print "/n";

### 後面是内容體...

由于都是文本,你可以很容易通過内置函數生成Expires和其他日期相關的頭資訊。如果你使用Cache-Control: max-age;會更簡單;

print "Cache-Control: max-age=600/n";

這樣腳本可以在被請求後緩存10分鐘;這樣使用者如果按“後退”按鈕,他們不會重新送出請求;

CGI的規範同時也允許用戶端發送頭資訊,每個頭資訊都有一個‘HTTP_’的字首;這樣如果一個用戶端發送一個If-Modified-Since請求,就是這樣的:

HTTP_IF_MODIFIED_SINCE = Fri, 30 Oct 1998 14:19:41 GMT

SSI(經常使用.shtml擴充名)是網站釋出者最早可以生成動态内容的方案。通過在頁面中設定特别的标記,也成為一種嵌入HTML的腳本;

PHP是一個内建在web伺服器中的伺服器端腳本語言,當做為HTML嵌入式腳本,很像SSI,但是有更多的選項,PHP可以在各種Web伺服器上設定為CGI模式運作,或者做為Apache的子產品;

預設PHP生成副本沒有設定校驗器,于是也無法緩存,但是開發者可以通過Header()函數來生成HTTP的頭資訊;

例如:以下代碼會生成一個Cache-Control頭資訊,并設定為3天以後過期的Expires頭資訊;

&lt;?php

 Header("Cache-Control: must-revalidate");

 $offset = 60 * 60 * 24 * 3;

 $ExpStr = "Expires: " . gmdate("D, d M Y H:i:s", time() + $offset) . " GMT";

 Header($ExpStr);

?&gt;

記住: Header()的輸出必須先于所有其他HTML的輸出;

&lt;CFHEADER NAME="Expires" VALUE="#Now()#"&gt;

它并不像你想像的那樣工作,因為時間(本例中為請求發起的時間)并不會被轉換成一個符合HTTP時間,而且列印出副本的Cold fusion的日期/時間對象,大部分用戶端會忽略或者将其轉換成1970年1月1日。

但是:Cold Fusion另外提供了一套日期格式化函數, GetHttpTimeSTring. 結合DateAdd函數,就很容易設定過期時間了,這裡我們設定一個Header聲明副本在1個月以後過期;

&lt;cfheader name="Expires" value="#GetHttpTimeString(DateAdd('m', 1, Now()))#"&gt;

你也可以使用CFHEADER标簽來設定Cache-Control: max-age等其他頭資訊;

記住:Web伺服器也會将頭資訊設定轉給Cold Fusion(做為CGI運作的時候),檢查你的伺服器設定并确定你是否可以利用伺服器設定代替Cold Fusion。

在asp中設定HTTP頭資訊是:确認Response方法先于HTML内容輸出前被調用,或者使用 Response.Buffer暫存輸出;同樣的:注意某些版本的IIS預設設定會輸出Cache-Control: private 頭資訊,必須聲明成public才能被共享緩存伺服器緩存。

IIS的ASP和其他web伺服器都允許你設定HTTP頭資訊,例如: 設定過期時間,你可以設定Response對象的屬性;

&lt;% Response.Expires=1440 %&gt;

設定請求的副本在輸出的指定分鐘後過期,類似的:也可以設定絕對的過期時間(确認你的HTTP日期格式正确)

&lt;% Response.ExpiresAbsolute=#May 31,1996 13:30:15 GMT# %&gt;

Cache-Control頭資訊可以這樣設定:

&lt;% Response.CacheControl="public" %&gt;

在ASP.NET中,Response.Expires 已經不推薦使用了,正确的方法是通過Response.Cache設定Cache相關的頭資訊;

Response.Cache.SetExpires ( DateTime.Now.AddMinutes ( 60 ) ) ;

Response.Cache.SetCacheability ( HttpCacheability.Public ) ;

HTTP 1.1的規範有大量的擴充用于頁面緩存,以及權威的接口實作指南,參考章節:13, 14.9, 14.21, 以及 14.25.

非常精彩的介紹緩存相關概念,并介紹其他線上資源。

<a href="http://www.goldmark.org/netrants/webstats/"></a>

Jeff Goldberg内容豐富的演說告訴你為什麼不應該過度依賴通路統計和計數器;

可緩存的引擎設計,檢測網頁并确定其如何與Web緩存伺服器互動, 這個引擎配合這篇指南是一個很好的調試工具,

包含庫:用于CGI模式運作的Perl/Python/PHP腳本,自動處理ETag生成/校驗,Content-Length生成和内容壓縮。正确地。 Python版本也被用作其他大量的CGI腳本。

如果你鏡像本文,請通過以上郵件告知,這樣你可以在更新時被通知;

所有的商标屬于其所有人。

雖然作者确信内容在釋出時的正确性,但不保證其應用或引申應用的正确性,如有誤傳,錯誤或其他需要澄清的問題請盡快告知作者;

版本: 1.81 - 2007年3月16日

<a href="http://creativecommons.org/licenses/by-nc-nd/2.0/deed.zh">創作共用版權聲明</a>