緩存對於web開發有重要做用,尤爲是大負荷web系統開發中。 php
緩存分不少種:服務器緩存,第三方緩存,瀏覽器緩存等。其中瀏覽器緩存是代價最小的,由於瀏覽器緩存依賴的是客戶 端,而幾乎不耗費服務器端的資源。 html
讓瀏覽器作緩存須要給瀏覽器發送指定的Http頭,告訴瀏覽器緩存多長時間,或者堅定不要緩存。 web
1.Expires(過時時間)HTTP頭信息Expires(過時時間) 屬性是HTTP控制緩存的基本手段,這個屬性告訴緩存器:相關副本在多長時間內是新鮮的。過了這個時間,緩存器就會向源服務器發送請求,檢查文檔是否被修 改。幾乎全部的緩存服務器都支持Expires(過時時間)屬性; 瀏覽器
大部分Web服務器支持你用幾種方式設置Expires屬性;通常 的:能夠設計一個絕對時間間隔:基於客戶最後查看副本的時間(最後訪問時間)或者根據服務器上文檔最後被修改的時間; 緩存
Expires 頭信息:對於設置靜態圖片文件(例如導航欄和圖片按鈕)可緩存特別有用;由於這些圖片修改不多,你能夠給它們設置一個特別長的過時時間,這會使你的網站對 用戶變得相應很是快;他們對於控制有規律改變的網頁也頗有用,例如:你天天早上6點更新新聞頁,你能夠設置副本的過時時間也是這個時間,這樣緩存 服務器就知道何時去取一個更新版本,而沒必要讓用戶去按瀏覽器的「刷新」按鈕。 服務器
過時時間頭信息屬性值只能是HTTP格式的日期時間,其餘的都會被解析成當前時間「以前」,副本會過時,記住:HTTP的日期時間必須是格林威治時 間(GMT),而不是本地時間。舉例:
Expires: Fri, 30 Oct 1998 14:19:41 網絡
因此使用過時時間屬性必定要確認你的Web服務器時間設置正確,一個途徑是經過網絡時間同步協議(Network Time Protocol NTP),和你的系統管理員那裏你能夠了解更多細節。 測試
雖然過時時間屬性很是有用,可是它仍是有些侷限,首先:是牽扯到了日期,這樣Web服務器的時間和緩存服務器的時間必須是同步的,若是有些不一樣步, 要麼是應該緩存的內容提早過時了,要麼是過時結果沒及時更新。 網站
還有一個過時時間設置的問題也不容忽視:若是你設置的過時時間是一個固定的時間,若是你返回內容的時候又沒有連帶更新下次過時的時間,那麼以後全部 訪問請求都會被髮送給源Web服務器,反而增長了負載和響應時間; ui
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: max-age=3600, must-revalidate
給靜態資源(HTML文件,圖片文件等)的Repsone加上Expires/Cache-Control Header是頗有效的一招。若是HTTP Response中有Expires這樣的Header的話,瀏覽器會Cache這個資源,理想情況下(注意,只是理想情況),在Expire Date以前,不會再發HTTP請求給Server要這個資源,不過Expires的值只能是一個固定日期,好比「Thu 27 Nov 2008 07:00:00 GMT」,不能是一個相似「從如今開始以後10年」這樣一個隨機浮動的值,若是要這樣的效果,能夠用Cache-Control這樣的Header,若是 HTTP Response中有這樣的Header:「Cache-Control: max-age = 100」,表示這個資源在cache中的最大壽命是100秒。通常說來這種靜態文件永遠不該該過時,若是真的要給這個Cache加上一個期限,那我但願是 ——一萬年,「Cache-Control: max-age = 315360000000」
其實就應該給Expires設一個永遠不會過時的時間,好比你如今有一個文件叫logo.gif,須要用一個新的logo的時候,你不要去 覆蓋原來的文件,而把新的logo存成logo_v2.gif,讓相關網頁引用新的logo_v2.gif,這樣可讓新老網頁同時工做,實在犯不上爲了 節省存儲空間覆蓋原有文件。
對Apache服務器,使用mod_expires,在httpd.conf或者.htaccess中加上
<FilesMatch "\\.(ico|gif|jpg|html)$">ExpiresDefault "access plus 10 years"</FileMatch>
有些數據隨時都在變化。 CNN.com 的主頁常常幾分鐘就更新。另外一方面,Google.com 的主頁幾個星期才更新一次 (當他們上傳特殊的假日 logo,或爲一個新服務做廣告時)。 Web 服務是不變的:一般服務器知道你所請求的數據的最後修改時間,而且 HTTP 爲服務器提供了一種將最近修改數據連同你請求的數據一同發送的方法。
若是你第二次 (或第三次,或第四次) 請求相同的數據,你能夠告訴服務器你上一次得到的最後修改日期:在你的請求中發送一個 If-Modified-Since 頭信息,它包含了上一次從服務器連同數據所得到的日期。若是數據從那時起沒有改變,服務器將返回一個特殊的 HTTP 狀態代碼 304,這意味着 「從上一次請求後這個數據沒有改變」。這一點有何進步呢?當服務器發送狀態編碼 304 時,再也不從新發送數據。您僅僅得到了這個狀態代碼。因此當數據沒有更新時,你不須要一次又一次地下載相同的數據;服務器假定你有本地的緩存數據。
全部現代的瀏覽器都支持最近修改 (last-modified) 的數據檢查。若是你曾經訪問過某頁,一天後從新訪問相同的頁時發現它沒有變化,並奇怪第二次訪問時頁面加載得如此之快——這就是緣由所在。你的瀏覽器首次 訪問時會在本地緩存頁面內容,當你第二次訪問,瀏覽器自動發送首次訪問時從服務器得到的最近修改日期。服務器簡單地返回 304: Not Modified (沒有修改),所以瀏覽器就會知道從本地緩存加載頁面。在這一點上,Web 服務也如此智能。
ETag 是實現與最近修改數據檢查一樣的功能的另外一種方法:沒有變化時不從新下載數據。其工做方式是:服務器發送你所請求的數據的同時,發送某種數據的 hash (在 ETag 頭信息中給出)。hash 的肯定徹底取決於服務器。當第二次請求相同的數據時,你須要在 If-None-Match: 頭信息中包含 ETag hash,若是數據沒有改變,服務器將返回 304 狀態代碼。與最近修改數據檢查相同,服務器僅僅 發送 304 狀態代碼;第二次將不爲你發送相同的數據。在第二次請求時,經過包含 ETag hash,你告訴服務器:若是 hash 仍舊匹配就沒有必要從新發送相同的數據,由於你還有上一次訪問過的數據。
這幾個http頭能夠做爲meta標籤發送到客戶端,可是須要注意的是Http頭中的設置優先級更高一些,例如:
<meta http-equiv="Expires" CONTENT=" Fri, 30 Oct 1998 14:19:41">
<meta http-equiv="Cache-Control" CONTENT="no-cache">
Expires/Cache-Control Header是控制瀏覽器是否直接從瀏覽器緩存取數據仍是從新發請求到服務器取數據。只是Cache-Control比Expires能夠控制的多一些, 並且Cache-Control會重寫Expires的規則。
Last-Modified/If-Modified-Since和ETag/If-None-Match是瀏覽器發送請求到服務器後判斷文件是否 已經修改過,若是沒有修改過就只發送一個304回給瀏覽器,告訴瀏覽器直接從本身本地的緩存取數據;若是修改過那就整個數據從新發給瀏覽器。
--------------------------------
本文連接: http://www.php-oa.com/2008/12/03/http-head.html
測試而無聊的過程就懶的寫了…下面直接給結果出來.
根據個人測試no-cache>Expires>refresh_pattern>Last-Modified
也就是講,最前面的最重要,前面的生效後,後面的基本就失效了.
另外squid自己就能對比Last-Modified,但根據個人測試,Etag仍是會要向源服務器發送請求頭,來確認etag的.
ETag默認是須要向源網站確認的.
Last-Modified默認是不向源服務器確認的.