Web開發人員需知的Web快取知識

cyxlzzs發表於2013-06-14

原文出處:mnot譯文出處:張鑫旭

最近的譯文距今已有4年之久,原文有一定的更新。今天踩著前輩們的肩膀,再次把這篇文章翻譯整理下。一來讓自己對web快取的理解更深刻些,二來讓大家注意力稍稍轉移下,不要整天HTML5, 面試題啊叨啊叨的~~

什麼是Web快取,為什麼要使用它?

Web快取遊走於伺服器和客戶端之間。這個伺服器可能是源伺服器(資源所駐留的伺服器Add),數量可能是1個或多個;這個客戶端也可能是1個或多個。Web快取就在伺服器-客戶端之間搞監控,監控請求,並且把請求輸出的內容(例如html頁面、 圖片和檔案)(統稱為副本)另存一份;然後,如果下一個請求是相同的URL,則直接請求儲存的副本,而不是再次麻煩源伺服器。

使用快取的2個主要原因:

  • 降低延遲:快取離客戶端更近,因此,從快取請求內容比從源伺服器所用時間更少,呈現速度更快,網站就顯得更靈敏。
  • 降低網路傳輸:副本被重複使用,大大降低了使用者的頻寬使用,其實也是一種變相的省錢(如果流量要付費的話),同時保證了頻寬請求在一個低水平上,更容易維護了。

Web快取的型別

1.瀏覽器快取
在任何現代瀏覽器上(如IE, FireFox, Chrome)折騰清除隱私資料(//zxx: 原文說的是首選項,顯然out了,這裡有改動)的對話方塊,你很可能會注意到“快取”這個設定項。

web製作、開發人員需知的Web快取知識

瀏覽器會在你的硬碟上專門開闢一個空間專門為你儲存資源副本。瀏覽器快取的工作規則很簡單:檢查以確保副本是最新的,通常只要一次會話(就是當前瀏覽器呼叫的這次N)。

瀏覽器快取在使用者觸發“後退”操作或點選一個之前看過的連結的時候很管用。同樣,如果你在網站上訪問同一張圖片,該圖片可以從瀏覽器快取中調出並幾乎立即顯現出來。

2. 代理伺服器快取
Web代理伺服器使用同樣的快取原理,只是規模更大。代理以同樣的方式服務千萬使用者,大公司和ISP(Internet Server Provider, Internet服務提供商Add)經常在他們的防火牆或者單獨的裝置(也被稱為中介(intermediaries))上架設代理快取。

由於代理伺服器快取並非客戶端或者源伺服器的一部分,而是處於網路中,請求需要以某種方式路由到它們。一種方法是手動設定,告訴瀏覽器的你常用的代理伺服器(//zxx: 的時候常用的),另外就是使用攔截。攔截代理(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快取無害嗎?為什麼要鼓勵快取?

Web快取是網際網路中最容易被誤解的技術之一。網站管理員特別希望知道網站的一舉一動,比方說多少人訪問啦,訪問時間啊什麼的,而快取會“隱藏”他們的使用者,他們就無從得知到底誰訪問了這個站點。

撿了芝麻丟西瓜,自認為放棄快取可以精確跟蹤使用者,實際上,網際網路中有太多的變數,想精確得到一張使用者檢視網站的圖片?沒那麼簡單的,親!如果你很重視這個問題,恭喜你,本文正好提供瞭解決之道,即保證快取友好,同時又能獲得統計。

另外需要注意的是,快取的內容都是舊的過時的。因此,如何準確更新就成了一個問題。不過不要擔心,本文會向你展示如何配置伺服器,讓快取就像你的女僕——隨便調教。

web製作、開發人員需知的Web快取知識

CDN算是個挺有意思的技術,不同於代理快取,CDN的閘道器快取和被快取的Web站點的利益是一致的,因此,上面提到的問題對於CDN而言是沒有的。不過,即使你使用了CDN,你仍要顧慮下游的代理和瀏覽器快取。

以上為快取可能的“糟粕”,那他好的地方呢?快取可以讓你的Web站點載入更快,讓你的伺服器和網際網路連結間負擔更小。這種差異會導致一些類似質的 變化,一個網站要幾秒鐘才能載入出來,而另外一個充分發揮快取的優勢,幾乎瞬間顯示。使用者自然更喜歡那個載入迅速的站點,訪問也更多。

再說個現實示例,許多大型網際網路公司花費了數百萬美元,在世界各地設立伺服器叢集來複制他們的內容,以使其儘可能快被他們的使用者訪問。快取為你做同樣的事情,而且他們更接近終端使用者。最重要的是,你不要花銀子。

實際上呢,無論你喜歡與否,代理和瀏覽器快取都會被使用。如果你站點的快取配置不正確,你只能聽天由命了。

Web快取如何工作

所以的快取都有一套自己的規則,可以用來決定何時跟快取曖昧往來。其中部分規則設定在協議中(HTTP 1.0 以及 1.1),部分由快取管理員⑤設定。

⑤快取管理員:如果指的是瀏覽器快取,則有可能就是我們伺服器專家同事,在伺服器上配置一些快取規則;如果是代理快取,則指的就是處理代理伺服器這塊的管理人員。

一般而言有如下常用規則N

  1. 響應頭明確說明,偶不想被快取,則不會被快取;
  2. 如果請求資訊是需要認證或者安全加密的(如, HTTPS),相應內容也不會被快取;
  3. 快取如果有以下表現,則認為是fresh新鮮的(無需檢查源伺服器,直接傳送給客戶端):
    • 含有完整的過期時間和壽命控制頭資訊,並且內容仍在保鮮期內,或者
    • 快取最近已展現,並且在不久前修改。

    則內容快取直取,繞過源伺服器。

  4. 若內容陳舊,則會要求源伺服器做驗證validate,或者告訴快取其拷貝副本是否是OK的。
  5. 特定情況下——例如,斷網了,之前有過的響應快取直取而不檢查源伺服器。

響應如果沒有類似ETagLast-Modified頭這樣的校驗器,也沒有明確的更新資訊,通常(並不絕對)認為是不可快取的。

總而言之,新鮮度freshness校驗validation是確定快取內容是否可用的最重要途徑。如果要展示的足夠新,直接快取取;如果檢測發現展示內容並未變化,則不會再來一次完整的傳輸。

如何控制快取和不快取

有很多工具可以幫助設計師和網站管理員調整伺服器快取網站的方式,這也許需要你親自動手對伺服器的配置進行一些調整,但絕對值得。瞭解如何使用這些工具請參考本文後面的章節。

HTML Meta標籤 vs. HTTP頭資訊
HTML重構人員可以在文件的<head>中新增標籤進行描述。這些meta標籤通常用來標記不可快取或過期時間。

Meta標籤使用簡單,但效果一般。因為只被少數幾個瀏覽器寵幸,而代理快取基本上就不訪問HTML文件。儘管我們可以在頁面上試圖新增no-cachemeta標籤讓頁面一直是最新的,但其實沒必要。

如果你的網站託管在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=[秒]:表示在這個時間範圍內快取是新鮮的無需更新。類似Expires時間,不過這個時間是相對的,而不是絕對的。也就是某次請求成功後多少秒內快取是新鮮的。
  • s-maxage=[秒]:類似max-age, 除了僅應用於共享快取(如代理)。
  • public:標記認證的響應才能夠被快取。一般而言,需要認證HTTP請求內容會自動私有化(不會被快取Add)。
  • privateN:允許快取專門為某一個使用者儲存響應,比方說在瀏覽器中;共享快取一般不會,例如在代理中。
  • no-cache:每次在釋放快取副本之前都強制傳送請求給源伺服器進行驗證,這在確保認證有效性上很管用(和public結合使用)或者保證內容必須是即時的,不得無視快取的所有優點,如國內的微博、twitter等的重新整理顯示Add
  • no-store:強制快取在任何情況下都不要保留任何副本。
  • must-revalidate:告訴快取,我給你準備了一些關於新鮮度的資訊,在表現的時候要嚴格遵循之。HTTP允許快取在某些特定情況下返回過期資料,指定了這個屬性,相對於告訴快取,你丫必須嚴格遵循我的規則。
  • proxy-revalidate:類似must-revalidate,除了只能應用於代理快取。

舉個板栗:

Cache-Control: max-age=3600, must-revalidate

如果Cache-ControlExpires同時存在,Cache-Control說了算N。如果你打算使用Cache-Control頭,你應該好好看看”HTTP 1.1 規範“, 詳見參考文章以及擴充閱讀。

驗證器和驗證
在快取如何工作這段譯文中,我們說過,伺服器以及快取通過驗證來判斷內容是否改變,在不確定內容是否過期的時候,可以避免本地已經存在副本的時候下載整個內容。

驗證器是很重要的,如果一個都沒有,同時沒有可用的新鮮度資訊(ExpiresCache-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伺服器都對靜態內容(如:檔案)自動生成ETagLast-Modified頭資訊,而你不必做任何設定。但是,伺服器對於動態內容(例如:CGI, ASP或資料庫生成的網站)並不知道如何生成這些資訊,參考一下編寫支援快取的指令碼章節;

建立支援快取網站的小技巧

除了使用新鮮度資訊以及驗證,還有其他一些技巧可以讓你網站的快取更加友好:

  • 保持URL穩定:這是快取的金科玉律,如果你為不同頁面,不同使用者或不同網站提供相同的內容,他們應該使用相同的URL. 這是簡單卻非常行之有效的方法。例如,你的HTML中的某個引用地址是"/index.html", 則要一直使用這個地址。
  • 不同地方的圖片和其他元素使用同一庫
  • 對於不經常改變的圖片/頁面啟用快取,通過將Cache-Control: max-age頭資訊的值設大一點。
  • 對於定期更新的內容通過指定max-age或過期時間實現快取。
  • 如果資源改變了(尤其下載檔案),改變其名字。由於一般這種資源會有很長的過期時間,而伺服器上一直是正確的版本;因此,連結這個下載資源的頁面需要要比較短的過期時間(//zxx: 我司頁面5分鐘過期)。否則,會出現伺服器的資源是新的,但頁面被快取了,其中的連結地址還是舊的,就會出現新舊版本衝突的可能Add
  • 萬不得已不要變動檔案:否則你要設定一個新的Last-Modified值。另外,當你更新站點的時候,只要上傳改動的那些檔案,而不要把整個站點都覆蓋過去。
  • Cookie能不用就不用:Cookie難以被快取,且大多情境下是沒有必要的。如果你非得使用Cookie,建議用在動態頁面上。
  • 減少SSL⑧的使用:因為共享快取不能儲存認證頁面,只在必要的時候使用,並且在SSL頁面上減少圖片的使用。
  • 使用REDbot⑨檢查你的網站:可以幫助你應用本文所介紹的一些概念。

⑧ 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-ModifiedEtag響應頭)或新鮮度資訊(ExpiresCache-Control)。儘管有些指令碼的確是動態的(意味著每次請求都有不同的響應),還是有很多(如搜尋引擎或資料庫驅動的)網站可以從快取中受益。

一般來講,對於同一個請求(無論是幾分鐘還是幾天之後),如果指令碼產生的內容是可重複的,則可以快取。指令碼內容的改變僅僅依賴於URL,則可以快取。如果是依賴於Cookie,認證資訊或其他外部條件,很可能不快取。

  • 最利於快取的指令碼就是在內容改變時匯出成靜態檔案,伺服器會想對待其他Web一樣對待它的,生成以及使用驗證器,於是你可以好好地喝杯咖啡了。記住,只有檔案更改的時候才寫入,這樣Last-Modified時間就會被儲存下來。
  • 另外的指令碼快取之道就是使用age相關的頭部,相比Expires,Cache-Control: max-age更容易些,因為是相對時間,每次新請求完成後重新設定,時間到了,再重新請求,再設定新的相對過期時間。
  • 如果上面的做法你搞不定,你還可以試試通過指令碼生成一個校驗器, 然後迴應If-Modified-Since和/或If-None-Match請求。通過分析HTTP頭資訊,在適合的時候迴應304 Not Modified. 不幸的是,這不是個打打醬油就能搞定的任務。

其他一些技巧

  • 不要使用POST:若是獲取資料,儘量不使用POST模式,因為POST方式返回內容大部分不會被快取,相對的,通過GET以路徑和查詢傳送的資訊被快取儲存下來供後續使用。
  • URL地址中不要嵌入特定的使用者資訊,除非生成的內容對於使用者而言是唯一的。
  • 不要指望同一使用者的所有請求來自同一主機,因為快取經常協同工作。//zxx:嘛意思?
  • 生成Content-Length⑩頭資訊。實現不難,可讓你的指令碼以持久連線(persistent connection)形式響應。這允許客戶端在一個TCP/IP請求上請求多個內容,而不是為每次請求單獨建立連線,這樣你的網站相應會快很多。

詳見實現注意事項。

⑩Content-Length:指明實體正文的長度,以位元組方式儲存的十進位制數字來表示。在資料下行的過程中,Content-Length的方式要預先在伺服器中快取所有資料,然後所有資料再一股腦兒地發給客戶端。

常見問題解答

快取可用的最重要事情是?
其中一個不錯的策略是找出常用的、規模較大的內容(尤其圖片),然後優先處理之。

我該如何利用快取讓我的頁面儘可能的快?
最應該快取的內容設定一個較長的過期時間。驗證有助於減少檢視內容的時間,不過快取仍會連線源伺服器檢視是不是過期了。如果快取已經知道內容是新鮮的,直接返回。

我知道快取是個好東西,但是我想隨時知道多少人訪問了我的網頁!
如果你必須知道每一次頁面被訪問的情況,可以選擇頁面上的一個小元素(或頁面本身),然後給這個元素一個適當的頭資訊使它是不可快取。比如,你可以在每一個頁面上引用一個1畫素×1畫素的不可快取(如scr地址後面加個隨機數Add)的透明圖片。Referer頭資訊將會包含呼叫它的頁面資訊。

請注意,即使這樣也不能給出你使用者的精確統計,並且對通過網際網路訪問的使用者也不是很友好:產生不必要的流量,並強迫使用者等待未被快取的內容從網路上下載回來。更多的資訊可參見擴充閱讀中的“解讀訪問統計”對應內容。

我該如何檢視HTTP頭?
許多瀏覽器可以檢視ExpiresLast-Modified頭資訊,如右鍵→檢視頁面資訊或類似皮膚。例如,在Firefox瀏覽器下Add

web製作、開發人員需知的Web快取知識web製作、開發人員需知的Web快取知識

表示要看到完整的頭,您可以使用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]等同敲Enter鍵,最後輸入兩次確認。這樣就會輸出頭資訊,然後跟著實際內容。如果只想看到頭資訊,使用HEAD來替換GET.

⑪Telnet:Telnet協議是TCP/IP協議族中 的一員,是Internet遠端登陸服務的標準協議和主要方式。它為使用者提供了在本地計算機上完成遠端主機工作的能力。在終端使用者的電腦上使用 telnet程式,用它連線到伺服器。終端使用者可以在telnet程式中輸入命令,這些命令會在伺服器上執行,就像直接在伺服器的控制檯上輸入一樣。可 以在本地就能控制伺服器。要開始一個telnet會話,必須輸入使用者名稱和密碼來登入伺服器。Telnet是常用的遠端控制Web伺服器的方法。

我的頁面是密碼保護的,代理快取是怎麼處理的?
預設情況下,HTTP驗證保護的頁面是私有的,共享快取是不能儲存的。然而,你可以通過Cache-Control: public頭的設定使其公有。HTTP 1.1標準相容的快取伺服器可以使之快取。

如果你希望這些快取的頁面在使用者檢視之前還要驗證一下,可以組合使用Cache-Control: publicno-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伺服器端

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

Apache HTTP伺服器
Apache使用可選模組包含頭資訊,頭資訊ExpiresCache-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.2Nmod_expiresmod_headers文件。

微軟IIS
微軟的IIS有一些靈活的方式可以很容易得設定頭資訊,不過似乎只針對IIS 4.0伺服器,並且只能在NT伺服器上執行。

為了給網站某區域指定頭資訊,需要進入Administration(管理員)工具皮膚,然後再設定屬性。選擇HTTP Headers選項卡後,你會看到兩個有意思的區域:Enable Content ExpirationCustom HTTP headers, 第一個含義一目瞭然,第二個用來應用Cache-Control頭。//zxx: 此處的操作描述很過時了,看看window7下,操作介面早就大變樣了!

web製作、開發人員需知的Web快取知識web製作、開發人員需知的Web快取知識

設定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設定快取相關的頭資訊,如下:

1 Response.Cache.SetExpires ( DateTime.Now.AddMinutes (60) ) ;
2 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指令碼。

關於本文件

本文版權屬於Mark Nottingham © 1998-2013 郵箱為mnot@pobox.com.

本作品遵循知識共享署名 – 非商業性使用 – 禁止演繹3.0宣告頁面許可證N

所有的商標版權為其持有人所有。

內容在釋出時是可以確保其正確性,但是,隨著時間推移,就不能保證正確無誤了。因此,如有連結404,描述錯誤或其他需要糾正的問題請儘快告知作者。

本文最新版本可以從http://www.mnot.net/cache_docs/獲得

可用翻譯:白俄羅斯中國捷克德國法國

文件說明:含有上標N的表示與前輩翻譯時候相比新增的;上標Add表示作為譯者的我為了便於理解自己新增的;上標數字(①-⑬)是對一些可能不熟悉的名詞的百科解釋。

雖然原作語言不生動,教科書般一板一眼⑭;有些可能過時了。不過,還是學到了很多東西。還是很值的!歡迎分享,歡迎傳播,以後面試之前來這裡看看,可能會有幫助哦!

⑭ 如果我介紹快取,我可能就這麼講:快取是什麼?顧名思意,就是緩慢的存錢。為什麼要緩慢的存錢,因為工資卡都上交老婆了,為了攢點零花錢又不能被老婆發 現,只能慢慢存了。那快取有什麼用呢?你想啊,自己有點小錢,做事情就方便快捷了,比方說我想買個魚竿,就不要去向老婆要(給不給先不談),自己從自己這 邊取,大大提高了執行的速度。

那什麼時候可以存什麼時候不能存呢?老婆給零花錢的時候,可能會有過期時間頭,例如,週一甩了100塊錢,拿去,這是一週的伙食!這個一週就是過期時間頭(Expires Header),在這個時間內,你的錢可以從快取,也就是自己這裡取……

相關文章