首頁»WEB綜合»Web 開發人員需知的 Web 緩存知識

Web 開發人員需知的 Web 緩存知識

來源:張鑫旭 發布時間:2013-06-14 閱讀次數:

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

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

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

  使用緩存的2個主要原因:

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

  Web緩存的類型

  1. 瀏覽器緩存

  在任何現代瀏覽器上(如IE, FireFox, Chrome)折騰清除隱私數據(//zxx: 原文說的是首選項,顯然out了,這里有改動)的對話框,你很可能會注意到“緩存”這個設置項。

  瀏覽器會在你的硬盤上專門開辟一個空間專門為你存儲資源副本。瀏覽器緩存的工作規則很簡單:檢查以確保副本是最新的,通常只要一次會話(就是當前瀏覽器調用的這次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緩存是互聯網中最容易被誤解的技術之一。網站管理員特別希望知道網站的一舉一動,比方說多少人訪問啦,訪問時間啊什么的,而緩存會“隱藏”他們的用戶,他們就無從得知到底誰訪問了這個站點。

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

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

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

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

  再說個現實示例,許多大型互聯網公司花費了數百萬美元,在世界各地設立服務器集群來復制他們的內容,以使其盡可能快被他們的用戶訪問。緩存為你做同樣的事情,而且他們更接近最終用戶。最重要的是,你不要花銀子。

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

  Web緩存如何工作

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

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

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

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

    則內容緩存直取,繞過源服務器。

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

  響應如果沒有類似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=[秒]:表示在這個時間范圍內緩存是新鮮的無需更新。類似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-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或數據庫生成的網站)并不知道如何生成這些信息,參考一下編寫支持緩存的腳本章節;

  創建支持緩存網站的小技巧

  除了使用新鮮度信息以及驗證,還有其他一些技巧可以讓你網站的緩存更加友好:

  • 保持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-Modified或Etag響應頭)或新鮮度信息(Expires或Cache-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頭?

  許多瀏覽器可以查看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服務器端

  一般說來,應該選擇最新版本的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模塊,其允許你為資源指定任意的頭信息??蓞⒖?a target="_blank">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_expiresmod_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腳本。

  關于本文檔

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

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

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

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

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

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

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

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

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

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

QQ群:WEB開發者官方群(515171538),驗證消息:10000
微信群:加小編微信 849023636 邀請您加入,驗證消息:10000
提示:更多精彩內容關注微信公眾號:全棧開發者中心(fsder-com)
網友評論(共1條評論) 正在載入評論......
理智評論文明上網,拒絕惡意謾罵 發表評論 / 共1條評論
登錄會員中心
大发国际网址 福安市| 治县。| 寿光市| 潜江市| 怀柔区| 炉霍县| 达拉特旗| 沈阳市| 大化| 闻喜县| 二手房| 原平市| 灵山县| 囊谦县| 武安市| 大洼县| 永仁县| 于田县| 巴中市| 万州区| 阳泉市| 溧阳市| 抚远县| 英德市| 临江市| 凉山| 永宁县| 龙游县| 沾益县| 霍林郭勒市| 依兰县| 社旗县| 同德县| 分宜县| 潮州市| 上饶县| 定安县| 江都市| 始兴县| 咸宁市| 黑山县| 山丹县| 开远市| 灵寿县| 买车| 来凤县| 南江县| 迭部县| 丘北县| 通化市| 无为县| 札达县| 黄大仙区| 文登市| 安乡县| 岳池县| 安化县| 南城县| 渑池县| 高清| 青浦区| 密山市| 周口市| 霸州市| 东源县| 赤峰市| 乌兰浩特市| 黄骅市| 彭州市| 安徽省| 林周县| 合阳县| 娄底市| 重庆市| 灌云县| 罗江县| 淮滨县| 娱乐| 合阳县| 扶沟县| 南江县| 南木林县| 报价| 麻栗坡县| 色达县| 新宁县| 绥宁县| 泽库县| 凯里市| 通榆县| 曲阳县| 桓仁| 和林格尔县| 遵化市| 龙里县| 万宁市| 称多县| 兴城市| 淮安市| 平顶山市| 丰原市| 阿勒泰市| 齐齐哈尔市| 高州市| 沛县| 新龙县| 麻阳| 大关县| 内丘县| 饶平县| 道孚县| 军事| 长阳| 开平市| 鄄城县| 盐池县| 临汾市| 华阴市| 塔河县| 澄江县| 张家港市| 兴仁县| 宾阳县| 湘潭市| 楚雄市| 神木县| 秦安县| 库车县| 永修县| 旬阳县| 嵊泗县| 德惠市| 阜南县| 松滋市| 东兰县| 桂阳县| 茂名市|