最近的譯文距今已有4年之久,原文有必定的更新。今天踩着前輩們的肩膀,再次把這篇文章翻譯整理下。一來讓本身對web緩存的理解更深入些,二來讓你們注意力稍稍轉移下,不要成天HTML5, 面試題啊叨啊叨的~~php
Web緩存遊走於服務器和客戶端之間。這個服務器多是源服務器(資源所駐留的服務器Add),數量多是1個或多個;這個客戶端也多是1個或多個。Web緩存就在服務器-客戶端之間搞監控,監控請求,而且把請求輸出的內容(例如html頁面、 圖片和文件)(統稱爲副本)另存一份;而後,若是下一個請求是相同的URL,則直接請求保存的副本,而不是再次麻煩源服務器。html
使用緩存的2個主要緣由:web
1. 瀏覽器緩存
在任何現代瀏覽器上(如IE, FireFox, Chrome)折騰清除隱私數據(//zxx: 原文說的是首選項,顯然out了,這裏有改動)的對話框,你極可能會注意到「緩存」這個設置項。面試
瀏覽器會在你的硬盤上專門開闢一個空間專門爲你存儲資源副本。瀏覽器緩存的工做規則很簡單:檢查以確保副本是最新的,一般只要一次會話(就是當前瀏覽器調用的此次N)。算法
瀏覽器緩存在用戶觸發「後退」操做或點擊一個以前看過的連接的時候很管用。一樣,若是你在網站上訪問同一張圖片,該圖片能夠從瀏覽器緩存中調出並幾乎當即顯現出來。數據庫
2. 代理服務器緩存
Web代理服務器使用一樣的緩存原理,只是規模更大。代理以一樣的方式服務千萬用戶,大公司和ISP(Internet Server Provider, Internet服務提供商Add)常常在他們的防火牆或者單獨的設備(也被稱爲中介(intermediaries))上架設代理緩存。apache
因爲代理服務器緩存並不是客戶端或者源服務器的一部分,而是處於網絡中,請求須要以某種方式路由到它們。一種方法是手動設置,告訴瀏覽器的你經常使用的代理服務器(//zxx: FQ的時候經常使用的),另外就是使用攔截。攔截代理(Interception proxies)把Web請求根據本身的底層網絡重定向,所以,客戶端無需配置,甚至都不須要知道它們。//zxx: 維基百科上提供的幾種檢測攔截代理服務器存在的方法add,您如有興趣,能夠點擊這裏查看。瀏覽器
代理緩存屬於一種共享緩存;每每有大量的用戶使用,所以,其在下降延時和網絡流量上頗有用,畢竟每一個副本都被大量重用。//zxx: 這裏我有疑問:就算是放在代理服務器上,每次獲取仍是要經過網絡的啊,如何下降了網絡流量呢?但願誰能夠幫忙解惑下。緩存
3. 網關緩存
也被稱爲「反向代理緩存」或「替代緩存」。網關緩存一樣是起中介做用的,不過不是(素不相識、未曾謀面的Add)網絡管理員部署的,而多半是網站管理員(公司專門的運維工程師、或UED或程序組某人Add)他們本身部署,這樣更容易擴展與維護。安全
能夠有多種方法把請求路由到網關緩存,但一般使用某種形式的負載均衡器①,使它們中的一個或多個看起來像是源服務器。內容分發網絡②(CDNs)爲整個網絡(或部分)分配網關緩存,而後把這些緩存賣給須要的網站。Speedera③和Akamai④就是表明性的網絡內容發佈商。
①負載均衡器:是一種採用各類分配算法把網絡請求分散到一個服務器集羣中的可用服務器上去,經過管理進入的Web數據流量和增長有效的網絡帶寬,從而使網絡訪問者得到儘量最佳的聯網體驗的硬件設備。
②內容分發網絡:即CDN, 基本思路是儘量避開互聯網上有可能影響數據傳輸速度和穩定性的瓶頸和環節,使內容傳輸的更快、更穩定。經過在網絡各處放置節點服務器所構成的在現有的互聯網基礎之上的一層智能虛擬網絡,CDN系統可以實時地根據網絡流量和各節點的鏈接、負載情況以及到用戶的距離和響應時間等綜合信息將用戶的請求從新導向離用戶最近的服務節點上。其目的是使用戶可就近取得所需內容,解決 Internet網絡擁擠的情況,提升用戶訪問網站的響應速度。
③Speedera:是一家全球性的內容服務提供商,它與北美、歐洲以及亞太地區的1000多家大型運營商都有聯繫,併爲那些不想在本身服務器上寄存內容的公司提供軟件下載、媒體及其它服務管理等業務。05年的時候被下面要介紹的Akamai以$130m的價格給收購了。
④Akamai:美國Akamai是國際上最大的CDN服務商,它巨大的網絡分發能力在峯值時可達到15Tbps。Akamai公司是爲數很少的旨在消除Internet瓶頸和提升下載速度的幾家新公司之一,是一個致力於網絡交通提速的」內容發佈」公司,是波士頓高技術區最卓越的新興企業之一。Akamai公司向全球企業提供發送互聯網內容,匯流媒體和應用程序的服務(目前,該公司爲15個國家的企業管理着8000多臺服務器)。1998年,丹尼爾。L和麻省理工學院的一些研究人員一塊兒創立了這家公司,他在麻省理工學院的碩士論文構成了Akamai公司最初的」自由流」(Freeflow)技術的核心。
本教程重點在瀏覽器和代理緩存,儘管有些信息對網關緩存感興趣的人也適用。
Web緩存是互聯網中最容易被誤解的技術之一。網站管理員特別但願知道網站的一舉一動,比方說多少人訪問啦,訪問時間啊什麼的,而緩存會「隱藏」他們的用戶,他們就無從得知到底誰訪問了這個站點。
撿了芝麻丟西瓜,自認爲放棄緩存能夠精確跟蹤用戶,實際上,互聯網中有太多的變數,想精確獲得一張用戶查看網站的圖片?沒那麼簡單的,親!若是你很重視這個問題,恭喜你,本文正好提供瞭解決之道,即保證緩存友好,同時又能得到統計。
另外須要注意的是,緩存的內容都是舊的過期的。所以,如何準確更新就成了一個問題。不過不要擔憂,本文會向你展現如何配置服務器,讓緩存就像你的女僕——隨便調教。
CDN算是個挺有意思的技術,不一樣於代理緩存,CDN的網關緩存和被緩存的Web站點的利益是一致的,所以,上面提到的問題對於CDN而言是沒有的。不過,即便你使用了CDN,你仍要顧慮下游的代理和瀏覽器緩存。
以上爲緩存可能的「糟粕」,那他好的地方呢?緩存可讓你的Web站點加載更快,讓你的服務器和互聯網連接間負擔更小。這種差別會致使一些相似質的變化,一個網站要幾秒鐘才能加載出來,而另一個充分發揮緩存的優點,幾乎瞬間顯示。用戶天然更喜歡那個加載迅速的站點,訪問也更多。
再說個現實示例,許多大型互聯網公司花費了數百萬美圓,在世界各地設立服務器集羣來複制他們的內容,以使其儘量快被他們的用戶訪問。緩存爲你作一樣的事情,並且他們更接近最終用戶。最重要的是,你不要花銀子。
實際上呢,不管你喜歡與否,代理和瀏覽器緩存都會被使用。若是你站點的緩存配置不正確,你只能聽天由命了。
因此的緩存都有一套本身的規則,能夠用來決定什麼時候跟緩存曖昧往來。其中部分規則設定在協議中(HTTP 1.0 以及 1.1),部分由緩存管理員⑤設置。
⑤緩存管理員:若是指的是瀏覽器緩存,則有可能就是咱們服務器專家同事,在服務器上配置一些緩存規則;若是是代理緩存,則指的就是處理代理服務器這塊的管理人員。
通常而言有以下經常使用規則N:
則內容緩存直取,繞過源服務器。
響應若是沒有相似ETag或Last-Modified頭這樣的校驗器,也沒有明確的更新信息,一般(並不絕對)認爲是不可緩存的。
總而言之,新鮮度freshness和校驗validation是肯定緩存內容是否可用的最重要途徑。若是要展現的足夠新,直接緩存取;若是檢測發現展現內容並未變化,則不會再來一次完整的傳輸。
有不少工具能夠幫助設計師和網站管理員調整服務器緩存網站的方式,這也許須要你親自動手對服務器的配置進行一些調整,但絕對值得。瞭解如何使用這些工具請參考本文後面的章節。
HTML Meta標籤 vs. HTTP頭信息
HTML重構人員能夠在文檔的<head>
中添加標籤進行描述。這些meta標籤一般用來標記不可緩存或過時時間。
Meta標籤使用簡單,但效果通常。由於只被少數幾個瀏覽器寵幸,而代理緩存基本上就不訪問HTML文檔。儘管咱們能夠在頁面上試圖添加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頭信息請參考對應章節。
Pragma HTTP頭信息(以及爲何不起做用)
不少人認爲在HTTP頭信息中設置了Pragma: no-cache
後會讓內容沒法被緩存。但事實並不是如此:HTTP的規範中,響應型頭信息沒有任何關於Pragma屬性的說明,只說明瞭請求頭信息(瀏覽器發送給服務器的頭信息)中的Pragma屬性。雖然有少部分緩存會買帳,但大部分無視,使用Pragma沒做用。若要使用,試試下面的頭信息。
使用Expires HTTP頭信息控制不過時
Expires HTTP頭是控制緩存的基本手段,Expires的中文意思是「有效期」,顯然,就是告訴瀏覽器緩存的有效期。若是過時,緩存會檢查源服務器以肯定文件是否改變了。Expires頭幾乎每一個緩存都支持。
大部分的服務器容許你以多種方式設置Expires響應頭。一般,他們容許設置一個絕對過時時間,而後對比最後一次訪問的時候或者最後一次文檔修改的時候決定客戶端內容的獲取方式。
對於靜態圖片(如導航或按鈕的圖片)而言,Expires頭信息是至關有用的,由於圖片不怎麼修改,您能夠給圖片設置一個至關長的過時時間,這回讓你的用戶感受網站變快了。Expires對於控制有改變規律的網頁也頗有用,例如:你有一個新聞聚合頁面,天天早上6點鐘準時更新,您能夠設置緩存的過時時間也是這個點,因而緩存就能夠很聰明地知道何時該去重載新的內容,何時睡大覺。
Expires頭惟一的有效值是HTTP時間,其餘值都會被認爲是「前男朋友前女朋友」之類,不會去緩存的。注意:時間是格林威治時間(GMT),而不是本地時間。以下所示:
Expires: Fri, 30 Oct 1998 14:19:41 GMT
顯然,若是你要使用Expires頭,確保你的Web服務器時間的準備就很是重要了。使用網絡時間協議⑥(Network Time Protocol – NTP)不失爲一個號方法。若是你的身邊有本地系統管理員,能夠向他諮詢,或者查看下面的百科Add 。
儘管Expires頭頗有用,但它有必定的侷限性。首先,由於牽扯到時間,Web服務器端的時鐘必須和緩存的同步,不然極可能實現不了預期的結果——緩存把前女朋友當初現女朋友,把現女朋友看成過去式——那就悲劇了。
另一個問題是,你很容易忘記給某內容設置了一個特定時間,若是返回內容的時候沒有更新這個過時時間,則每一個請求都是上訪到服務器,反而增長了負載和響應時間。
⑥網絡時間協議(NTP): 以封包交換把兩臺電腦的時鐘同步化的網絡協議。NTP使用UDP端口123做爲傳輸層。它是用做抵銷可變延遲的影響。NTP是仍在使用中的最古老的網絡協議之一(在1985年前開始)。NTP最初由德拉瓦州大學的Dave Mills設計,他與一羣志願者仍在維護NTP。
Cache-Control(緩存控制)HTTP頭信息
HTTP 1.1引入了新的頭信息:Cache-Control
響應頭信息,讓網站的發佈者能夠更全面的控制他們的內容,更好地處理Expires的些限制。Cache-Control
有用的響應頭包括:
max-age
, 除了僅應用於共享緩存(如代理)。public
結合使用)或者保證內容必須是即時的,不得無視緩存的全部優勢,如國內的微博、twitter等的刷新顯示Add。must-revalidate
,除了只能應用於代理緩存。舉個板栗:
Cache-Control: max-age=3600, must-revalidate
若是Cache-Control
和Expires
同時存在,Cache-Control
說了算N。若是你打算使用Cache-Control
頭,你應該好好看看」HTTP 1.1 規範「, 詳見參考文章以及拓展閱讀。
驗證器和驗證
在緩存如何工做這段譯文中,咱們說過,服務器以及緩存經過驗證來判斷內容是否改變,在不肯定內容是否過時的時候,能夠避免本地已經存在副本的時候下載整個內容。
驗證器是很重要的,若是一個都沒有,同時沒有可用的新鮮度信息(Expires
或Cache-Control
),緩存一點兒都不會存儲內容。
最多見的驗證是經過Last-Modified
頭信息通訊肯定文檔最後的修改時間,若是緩存有內容存儲,會包含Last-Modified
信息的,輔助If-Modified-Since
請求,咱們能夠詢問服務器內容是否改變了。
HTTP 1.1引入了一個新的驗證器,稱爲Etag
⑦. Etag
是每次展示內容改變時候由服務器生成的惟一標識符,因爲服務器控制ETag
如何生成,當緩存發起If-None-Match
請求的時候,若是Etag
匹配,就能夠肯定展現內容實際上是同樣的。
⑦Etag: HTTP協議規格說明定義ETag爲」被請求變量的實體值」。另外一種說法是,ETag是一個能夠與Web資源關聯的記號(token)。典型的Web資源能夠一個Web頁,但也多是JSON或XML文檔。服務器單獨負責判斷記號是什麼及其含義,並在HTTP響應頭中將其傳送到客戶端,如下是服務器端返回的格式:ETag:」50b1c1d4f775c61:df3″客戶端的查詢更新格式是這樣的:If-None-Match : W / 「50b1c1d4f775c61:df3″若是ETag沒改變,則返回狀態304而後不返回,這也和Last-Modified同樣。測試Etag主要在斷點下載時比較有用。
幾乎全部的緩存使用Last-Modified
時間做爲驗證器,Etag
驗證也開始變得流行。
全部新一代的Web服務器都對靜態內容(如:文件)自動生成ETag
和Last-Modified
頭信息,而你沒必要作任何設置。可是,服務器對於動態內容(例如:CGI, ASP或數據庫生成的網站)並不知道如何生成這些信息,參考一下編寫支持緩存的腳本章節;
除了使用新鮮度信息以及驗證,還有其餘一些技巧可讓你網站的緩存更加友好:
"/index.html"
, 則要一直使用這個地址。Cache-Control: max-age
頭信息的值設大一點。max-age
或過時時間實現緩存。Last-Modified
值。另外,當你更新站點的時候,只要上傳改動的那些文件,而不要把整個站點都覆蓋過去。⑧ SSL:全稱Secure Socket Layer – 安全套接層,爲Netscape所研發,用以保障在Internet上數據傳輸之安全,利用數據加密(Encryption)技術,可確保數據在網絡上之傳輸過程當中不會被截取及竊聽。目前通常通用之規格爲40 bit之安全標準,美國則已推出128 bit之更高安全標準,但限制出境。只要3.0版本以上之I.E.或Netscape瀏覽器便可支持SSL。
⑨ REDbot:REDbot = RED + robot,是個機器人,檢查HTTP資源,看他們如何會表現,指出常見的問題,並提出改進建議。雖然它屬於HTTP一致性測試儀,但卻能夠找到很多HTTP相關問題。
默認狀況下,大多數的腳本不會返回驗證器(Last-Modified
或Etag
響應頭)或新鮮度信息(Expires
或Cache-Control
)。儘管有些腳本的確是動態的(意味着每次請求都有不一樣的響應),仍是有不少(如搜索引擎或數據庫驅動的)網站能夠從緩存中受益。
通常來說,對於同一個請求(不管是幾分鐘仍是幾天以後),若是腳本產生的內容是可重複的,則能夠緩存。腳本內容的改變僅僅依賴於URL,則能夠緩存。若是是依賴於Cookie,認證信息或其餘外部條件,極可能不緩存。
age
相關的頭部,相比Expires
, Cache-Control: max-age
更容易些,由於是相對時間,每次新請求完成後從新設置,時間到了,再從新請求,再設置新的相對過時時間。If-Modified-Since
和/或If-None-Match
請求。經過分析HTTP頭信息,在適合的時候迴應304 Not Modified
. 不幸的是,這不是個打打醬油就能搞定的任務。其餘一些技巧
詳見實現注意事項。
⑩Content-Length:指明實體正文的長度,以字節方式存儲的十進制數字來表示。在數據下行的過程當中,Content-Length的方式要預先在服務器中緩存全部數據,而後全部數據再一古腦兒地發給客戶端。
緩存可用的最重要事情是?
其中一個不錯的策略是找出經常使用的、規模較大的內容(尤爲圖片),而後優先處理之。
我該如何利用緩存讓個人頁面儘量的快?
最應該緩存的內容設置一個較長的過時時間。驗證有助於減小查看內容的時間,不過緩存仍會鏈接源服務器查看是否是過時了。若是緩存已經知道內容是新鮮的,直接返回。
我知道緩存是個好東西,可是我想隨時知道多少人訪問了個人網頁!
若是你必須知道每一次頁面被訪問的狀況,能夠選擇頁面上的一個小元素(或頁面自己),而後給這個元素一個適當的頭信息使它是不可緩存。好比,你能夠在每個頁面上引用一個1像素×1像素的不可緩存(如scr地址後面加個隨機數Add)的透明圖片。Referer頭信息將會包含調用它的頁面信息。
請注意,即便這樣也不能給出你用戶的精確統計,而且對經過互聯網訪問的用戶也不是很友好:產生沒必要要的流量,並強迫用戶等待未被緩存的內容從網絡上下載回來。更多的信息可參見拓展閱讀中的「解讀訪問統計」對應內容。
我該如何查看HTTP頭?
許多瀏覽器能夠查看Expires
和Last-Modified
頭信息,如右鍵→查看頁面信息或相似面板。例如,在Firefox瀏覽器下Add:
表示要看到完整的頭,您能夠使用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 [return] Host: www.example.com [return][return]
[return]
等同敲回車鍵,最後輸入兩次確認。這樣就會輸出頭信息,而後跟着實際內容。若是隻想看到頭信息,使用HEAD
來替換GET
.
?Telnet:Telnet協議是TCP/IP協議族中的一員,是Internet遠程登錄服務的標準協議和主要方式。它爲用戶提供了在本地計算機上完成遠程主機工做的能力。在終端使用者的電腦上使用telnet程序,用它鏈接到服務器。終端使用者能夠在telnet程序中輸入命令,這些命令會在服務器上運行,就像直接在服務器的控制檯上輸入同樣。能夠在本地就能控制服務器。要開始一個telnet會話,必須輸入用戶名和密碼來登陸服務器。Telnet是經常使用的遠程控制Web服務器的方法。
個人頁面是密碼保護的,代理緩存是怎麼處理的?
默認狀況下,HTTP驗證保護的頁面是私有的,共享緩存是不能保存的。然而,你能夠經過Cache-Control: public
頭的設置使其公有。HTTP 1.1標準兼容的緩存服務器能夠使之緩存。
若是你但願這些緩存的頁面在用戶查看以前還要驗證一下,能夠組合使用Cache-Control: public
和no-cache
頭,這相對於告訴緩存器它從緩存中送出內容前必須遞交客戶端的驗證給原始服務器。這個頭信息以下所示:
Cache-Control: public, no-cache
無論怎麼,這是最小化驗證最好的方法;例如,你的圖片不敏感,你能夠把它放在分離的目錄中,並配置你的服務對它們不作強制驗證。這樣,那些圖片就會很天然的被緩存了。
若是人們經過緩存訪問個人網站,我應該擔憂安全嗎?
SSL頁面不會被代理服務器緩存,因此這個你不須要擔憂。可是,代理服務器就好非SSL頁面請求以及URL抓取這口,你懂的,這是不安全的。無良的管理員可能就會收集網站用戶的信息,尤爲在URL中。
事實上,任何網絡管理員均可以收集你的客戶端和服務器端之間的這類信息。CGI ?腳本有個漏洞,會把用戶名和密碼放在自身的URL地址中,這很容易讓其餘人發現用戶的登錄信息。
若是你懂得互聯網安全的些基本機制,就不會對代理緩存感到任何驚訝。
?CGI:通用網關接口(Common Gateway Interface). 用於初始化軟件服務的服務器方接口。這套接口描述了Web服務器與同一計算機上的軟件的通訊方式。
通用網關接口,它是一段程序,運行在服務器上,提供同客戶端HTML頁面的接口,通俗的講CGI就像是一座橋,把網頁和WEB服務器中的執行程序鏈接起來,它把HTML接收的指令傳遞給服務器,再把服務器執行的結果返還給HTML頁;用CGI能夠實現處理表格,數據庫查詢,發送電子郵件等許多操做,最多見的CGI程序就是計數器。CGI使網頁變得不是靜態的,而是交互式的。
我在尋找一個集成的Web發佈解決方案。哪些是可緩存的?
這個是不肯定的。通常來講,越複雜的系統越難緩存。最差的狀況就是全部的內容都是動態生成,而且不提供校驗器,與緩存壓根無緣。你能夠和你供應商的技術人員溝通獲取更多信息,並參考下面實現注意事項。
個人圖片緩存一個月後纔到期,我如今就想變更!Expires
頭是繞不過去的,除非緩存(瀏覽器或者代理)空間不足纔會刪除副本,緩存副本會一直使用。
最有效的方法是修改連接,這樣會從源服務器獲取完整的新內容。請記住,調用圖片的這個頁面也會被緩存的,正因如此,咱們須要讓圖片以及其餘相似的靜態資源易緩存,而頁面呢能夠隨着自身的改變(例如改變了一個圖片的URL地址Add)即時更新。
若是你想擺脫特定緩存,重載內容,能夠試試強制刷新(在FireFox中,shift鍵+reload按鈕等同於處理Pragma: no-cache
請求頭)或者讓緩存管理員使用某些接口刪除內容。
我運行一個Web Hosting服務。我怎樣才能讓個人用戶發佈緩存友好的網頁?
若是你使用apahe,能夠考慮容許他們使用.htaccess
文件並提供相應的文檔。
不然你須要在每個虛擬主機上爲各類緩存屬性創建預約的區域。好比:你能夠指定一個叫/cache-1m
的目錄用來放讀取後要緩存一個月的內容,而後再建一個/no-cache
的目錄,並在頭信息中指定這麼目錄中的內容不被緩存。
無論上面你作的如何,總之最好優先給用戶量大的客戶作緩存處理。大部分服務器節約的流量以及負載都是來自高容量的網站。
我明明告訴網頁要好好緩存,但它總是去請求,怎麼破?
緩存服務器並不老是要求內容要保持並重用,某些條件下,他們是不保存不重用的,全部的緩存服務器都回基於文件的大小、類型(圖片、頁面…),或者服務器空間的剩餘來肯定如何緩存。若是你的文件比較大或很熱門,可能就不會被緩存。有些緩存服務器容許管理員決定哪些內容要存儲,有些緩存服務器容許內容長存緩存中,因此,它們老是可用的。
通常說來,應該選擇最新版本的Web服務器程序來部署。不只由於它們包含更多利於緩存的功能,新版本每每在性能和安全性方面都有不少的改善。
Apache HTTP服務器
Apache使用可選模塊包含頭信息,頭信息Expires
和Cache-Control
一併包含。這些模塊在1.2版本以上都支持。
這些模塊須要編譯到Apache中,雖然包含,可是默認並未開啓。爲了肯定相應模塊已經被啓用,找到httpd?程序,運行httpd -l
, 它會列出可用的模塊(注意,僅有內部編譯的模塊列表纔會顯示,在較新版本的Apache中,使用httpd -M
能夠包含動態加載的模塊N),咱們須要關注的是expires模塊(expires_module
)和headers模塊(headers_module
)。
?httpd:httpd是Apache超文本傳輸協議(HTTP)服務器的主程序。被設計爲一個獨立運行的後臺進程,它會創建一個處理請求的子進程或線程的池。
-enable -module=expires
和-enable-module=headers
參數(apache 1.3+). 參開Apache中的INSTALL文件。一旦你的Apache有了相應的模塊,你能夠使用mod_expires
指定過時的時間,要麼在.htaccess
文件,要麼在服務器的access.conf
文件。你能夠設置過時時間是從訪問時間開始仍是文件修改時間開始,並應用到特定類型文件上或設爲默認配置。查看官方該模塊文檔得到更多信息,或者遇到問題的時候向你身邊的apache專家討教。
爲應用Cache-Control
頭,你須要使用mod_headers
模塊,其容許你爲資源指定任意的頭信息。可參考mod_headers官方文檔。
下面是.htaccess
文件展現瞭如何使用頭信息:
.htaccess
文件容許Web發佈者使用配置文件中的指定。能夠影響目錄以及子目錄內容。和你的服務器管理員溝通下,看看它們是否可用。
### 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.html <Files index.html> Header append Cache-Control "public, must-revalidate" </Files>
mod_expires
會自動計算並插入Cache-Control:max-age
頭信息。Apache 2′s的配置和1.3相似,更多信息能夠參考2.2N的mod_expires和mod_headers文檔。
微軟IIS
微軟的IIS有一些靈活的方式能夠很容易得設置頭信息,不過彷佛只針對IIS 4.0服務器,而且只能在NT服務器上運行。
爲了給網站某區域指定頭信息,須要進入Administration
(管理員)工具面板,而後再設置屬性。選擇HTTP Headers
選項卡後,你會看到兩個有意思的區域:Enable Content Expiration
和Custom HTTP headers
, 第一個含義一目瞭然,第二個用來應用Cache-Control
頭。//zxx: 此處的操做描述很過期了,看看window7下,操做界面早就大變樣了!
設置ASP頁面(Active Server Pages)的頭信息能夠參考後面的ASP章節,也能夠經過ISAPI模塊設置頭信息,細節請參考MSDN。
Netscape/iPlanet企業服務器
3.6版本之後,企業版服務器已經不能以任何方式設置Expires
頭信息了。然而,其從3.0版本開始支持HTTP 1.1的功能。這意味着HTTP 1.1的緩存(代理服務器/瀏覽器)利用你對Cache-Control
的設置來得到。
爲了使用Cache-Control
頭,在管理員服務器中選擇Content Management | Cache Control Directives
(內容管理|緩存控制指令)。而後,使用資源選擇器(Resource Picker),選擇你但願設置頭信息的目錄。設置完頭信息後,點擊」肯定」。更多信息請參考NES手冊。
時刻謹記,在Web服務器上設置HTTP要比經過腳本設置輕鬆些。你能夠二者都試試。
由於服務器端的腳本主要是爲了動態內容,因此即便實際上內容能夠被緩存的,其也不會生成緩存很強的頁面。若是你的頁面內容常常變更,但不是每一個頁面都中槍,能夠考慮設置Cache-Control: max-age
頭信息,大部分用戶是在相對端的時間內再次訪問這個頁面。例如:用戶點擊「後退」按鈕,若是沒有任何驗證或新鮮度信息,他們將不得不等待,直到從服務器頁面從新下載才能看到它。
CGI
CGI腳本是生成內容最經常使用的技術之一。你能夠輕輕鬆鬆在請求發送給主體以前添加HTTP請求信息。大部分CGI實現都須要添加Content-Type
頭信息,例如這個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>
因爲都是文本,你能夠很容易經過內置函數生成Expires
和其餘日期相關的頭信息。若是你使用Cache-Control: max-age
會更簡單:
print "Cache-Control: max-age=600n";
上面腳本可讓請求完成後緩存10分鐘,所以,當用戶點擊「後退」按鈕的時候,就不會從新塗膠請求了。
CGI的規範同時也容許在腳本環境中,客戶端發送請求頭信息,每一個頭信息都有一個’HTTP_’的前綴。因而乎,若是一個客戶端發送一個If-Modified-Since
請求,就是這樣的:
HTTP_IF_MODIFIED_SINCE
可觀摩cgi_buffer庫,其能夠自動實現Etag
生成和驗證,Content-Length
生成及gzip內容,而全部這些實現,只須要一行include,就能夠爲Perl和Python寫CGI腳本。Python版本還能夠包裝任意的CGI腳本。
服務器端包含
SSI(擴展名一般是.shtml
)最先能夠生成動態內容的網站發佈方案。經過在頁面中使用特定的標籤,有必定限制的內HTML腳本就能夠使用了。大部分的SSI實現不設置驗證器,故沒法緩存。不過Apache服務器容許經過設置讓SSI文件可緩存,經過適當的文件並結合XbitHack full
指令設置組執行權限。欲瞭解更多信息,請參閱mod_include文檔。
PHP
PHP爲服務器端腳本語言,在服務器內置的時候,能夠在HTML頁面中內嵌使用,很像SSL,不過有更多的可選項。PHP能夠在任何Web服務器(Unix或Windows)或Apache模塊上做爲CGI使用。
默認狀況下,PHP生成的內容沒有分配驗證器,所以,不能緩存。不過,開發人員能夠經過Header()
函數設置HTTP頭信息。例如,建立Cache-Control
頭,過時時間爲3天:
<?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); ?>
記住Header()
須要在全部的輸出以前。
正如你看到的,你能夠手工建立HTTP日期。PHP沒有專門的函數(新版本已改進,請參考PHP的日期相關函數文檔)。固然,最簡單的仍是設置Cache-Control: max-age
頭信息,適用於大部分狀況。
更多內容,請參閱header手冊。
仍是cgi_buffer庫,只要一行包含,就能以PHP腳本形式自動實現Etag
生成和驗證,Content-Length
生成及gzip內容。
Cold Fusion
Cold Fusion是Macromedia的商業服務器端腳本引擎,而且支持多種Windows平臺,Linux平臺和多種Unix平臺。//zxx: 看到Macromedia心亮了半截,幾百年前就被收購的公司……此文未免太過期了點了~~你們這段能夠跳過了,幾乎沒有任何價值……
Cold Fusion經過CFHEADER標記設置HTTP頭信息相對容易。惋惜的是,如下的Expires頭信息的設置有些容易誤導:
<CFHEADER NAME="Expires" VALUE="#Now()#">
它並不像你想像的那樣工做,由於時間(本例中爲請求發起的時間)並不會被轉換成一個符合HTTP時間,並且打印出副本的Cold fusion的日期/時間對象,大部分客戶端會忽略或者將其轉換成1970年1月1日。
可是:Cold Fusion另外提供了一套日期格式化函數-GetHttpTimeSTring. 結合DateAdd函數,就很容易設置過時時間了,這裏咱們設置一個頭信息,聲明內容在1個月之後過時:
<cfheader name="Expires" value="#GetHttpTimeString(DateAdd('m', 1, Now()))#">
你也能夠使用CFHEADER
標籤設置Cache-Control: max-age
以及其餘頭信息。
記住,Web服務器也會將頭信息設置轉給Cold Fusion(作爲CGI運行的時候),檢查你的服務器設置並肯定你是否能夠利用服務器設置代替Cold Fusion.
ASP和ASP.NET
在asp中設置HTTP頭信息時,確保Response
方法調用在HTML內容輸出以前,或者使用Response.Buffer
暫存輸出。同時,注意某些版本的IIS默認設置會輸出Cache-Control: private
頭信息,必須聲明成public
才能被共享緩存服務器緩存。
ASP(Active Server Pages),IIS內置,也可用於其餘Web服務器,一樣容許你設置HTTP頭。例如設置過時時間,你能夠使用Response
自帶屬性:
<% Response.Expires=1440 %>
指定內容過時的分鐘數。Cache-Control
頭添加以下:
<% Response.CacheControl="public" %>
在ASP.NET中,Response.Expires
已經不推薦使用了,正確的方法是經過Response.Cache
設置緩存相關的頭信息,以下:
Response.Cache.SetExpires ( DateTime.Now.AddMinutes ( 60 ) ) ; Response.Cache.SetCacheability ( HttpCacheability.Public ) ;
HTTP 1.1規範
HTTP 1.1的規範對頁面緩存以及權威的接口實現指南有了大量的擴展,參考章節:13, 14.9, 14.21以及14.25 .
Web-Caching.com
對緩存概念有很好的介紹,而且有不少其餘在線資源的連接。
解讀訪問統計
Jeff Goldberg這篇內容豐富敘述會告訴你爲何不該該過分依賴訪問統計和計數器。//zxx 上世紀的復古頁面…
REDbot
檢查HTTP資源,以肯定它們如何與Web緩存交互,以及一般如何使用該協議。
cgi_buffer庫
只要包含一行Perl CGI, Python CGI以及PHP腳本,就能自動實現Etag
生成以及驗證,Content-Length
生成以及Gzip內容的正確編碼。Python版本還能夠包裝任意的CGI腳本。