通過HTTP頭控制瀏覽器的緩存


通過HTTP頭控制瀏覽器的緩存
       瀏覽器緩存是提高用戶體驗和提升程序性能的一個很重要的途徑,通過瀏覽器的緩存控制,可以對實時性要求不高的數據進行緩存,可以減少甚至不需要再次對服務器的請求就可以顯示數據。 

本文將介紹如果通過HTTP協議中的header來控制瀏覽器的緩存行為,建議大家在看的時候寫代碼試驗下,這樣對這些header的理解會更深一點。 

HTTP協議定義了四個可以用來控制瀏覽器緩存的HTTP頭,它們是: 

Last-Modified 
Expires 
Pragma: no-cache 
Cache-Control 

下面分別介紹HTTP/1.0和HTTP/1.1協議下的緩存解決方法。 

HTTP/1.0 

在HTTP/1.0協議中,Last-Modified是控制緩存的一個非常重要的HTTP頭。如果需要控制瀏覽器的緩存,服務器首先必須發送一 個以UTC時間為值的Last-Modifeid頭,當第二次訪問這個頁面時,瀏覽器會發送一個If-Modified-Since頭給服務器,讓服務器 判斷是否有必要更新內容,這個If-Modified-Since頭的值就是上次訪問頁面時,瀏覽器發送的Last-Modifeid頭的值。 

Expires是HTTP/1.0中另外一個很重要的HTTP頭,它表示緩存的存在時間,告訴客戶端瀏覽器在這個時間之前不對服務器發送請求,而直接使用瀏覽器的緩存。 

在HTTP/1.0中,可以使用Pragma: no-cache頭來告訴瀏覽器不要緩存內容,它相當於HTTP/1.1中的Cache-Control:no-cache。 

如果要使用HTTP/1.0協議來告訴客戶端(包括任何中介代理)是否要緩存數據,可以使用以下代碼,如果設置liftTime參數則告訴客戶端數據緩存的生命期為lifeTime的值: 

Php代碼
function http_10_cache_headers($lifeTime = null){  
    $gmtime = time();  
    if ($lifeTime){  
        $gmtime += $lifeTime;  
    }else {  
        header("Pragma: no-cache");  
    }  
    $gmtime = gmdate('D, d M Y H:i:s',$gmtime).' GMT';  
    header("Last-Modified: $gmtime");  
    header("Expires: $gmtime");  
}  
function http_10_cache_headers($lifeTime = null){ $gmtime = time(); if ($lifeTime){ $gmtime += $lifeTime; }else { header("Pragma: no-cache"); } $gmtime = gmdate('D, d M Y H:i:s',$gmtime).' GMT'; header("Last-Modified: $gmtime"); header("Expires: $gmtime"); }

HTTP/1.0協議的這種實現方式的缺點是,服務器和客戶端的時間有可能是不同步的,這樣會造成緩存的實現達不到預期效果。HTTP/1.1協議用Cache-Control頭解決了這個問題。 

HTTP/1.1 

Cache-Control響應頭的語法為: 
Cache-Control = “Cache-Control” “:”; #緩存響應指令 

緩存響應指令為一下幾個中的任意一個: 

1. public 
2. private 
3. no-cache 
4. no-store 
5. no-transform 
6. must-revalidate 
7. proxy-revalidate 
8. max-age=時間 
9. s-maxage=時間 

詳細介紹一下這幾個指令的具體含義: 

1. public 指示響應數據可以被任何客戶端緩存 
2. private 指示響應數據可以被非共享緩存所緩存。這表明響應的數據可以被發送請求的瀏覽器緩存,而不能被中介所緩存 
3. no-cache 指示響應數據不能被任何接受響應的客戶端所緩存 
4. no-store 指示所傳送的響應數據除了不能被緩存,也不能存入磁盤。一般用於敏感數據,以免數據被復制。 
5. must-revalidate 指示所有的緩存都必須重新驗證,在這個過程中,瀏覽器會發送一個If-Modified-Since頭。如果服務器程序驗證得出當前的響應數據為最新的數 據,那么服務器應當返回一個304 Not Modified響應給客戶端,否則響應數據將再次被發送到客戶端。 
6. proxy-revalidate 與must-revalidate相似,不同的是用來指示共享緩存。 
7. max-age 數據經過max-age設置的秒數后就會失效,相當於HTTP/1.0中的Expires頭。如果在一次響應中同時設置了max-age和 Expires,那么max-age將具有較高的優先級。 
8. s-maxage 與max-age相似,不同的是用來指示共享緩存。 

了解這些指令后就可以根據不同的需求來發送不同的HTTP頭。
有關客戶端瀏覽器緩存的Http頭介紹
做網站開發離不開緩存,緩存分好多種:服務器緩存,第三方緩存,瀏覽器緩存等。其中瀏覽器緩存是代價最小的,因為瀏覽器緩存依賴的是客戶端,而幾乎不耗費服務器端的資源。

讓瀏覽器做緩存需要給瀏覽器發送指定的Http頭,告訴瀏覽器緩存多長時間,或者堅決不要緩存。作為.net的程序員,其實我們一直都在用這種方法,在OutputCache指令中指定緩存的Location為Client時,其實就是給瀏覽器發送了一個Http頭,告訴瀏覽器這個Url要緩存多長時間,最后修改的時間。

微軟在OutputCacheModule中對這些緩存用到的Http頭給我們進行了很好的封裝,但是了解這些Http頭可以更靈活的使用它們。

和客戶端緩存相關的Http頭有以下幾個,分別是:
1. Expires:+過期時間
表示在指定時間后瀏覽器緩存失效,需要注意的是這兒的過期時間必須是HTTP格式的日期時間,其他的都會被解析成當前時間“之前”,緩存會馬上過期,HTTP的日期時間必須是格林威治時間(GMT),而不是本地時間。舉例: 
Expires: Fri, 30 Oct 2009 14:19:41

使用Expires過期必須要求服務器的時間是正確的,否則發送的http頭就會出問題,在windows服務下可以設置時間服務器來同步時間
2. Cache-control: 
Cache-control直譯成中文就是緩存控制,它的作用就是緩存控制,這個http頭的值有幾種。
1) max-age=[秒] — 執行緩存被認為是最新的最長時間。類似於過期時間,這個參數是基於請求時間的相對時間間隔,而不是絕對過期時間,[秒]是一個數字,單位是秒:從請求時間開始到過期時間之間的秒數。 
2) s-maxage=[秒] — 類似於max-age屬性,除了他應用於共享(如:代理服務器)緩存 
3) public — 標記認證內容也可以被緩存,一般來說: 經過HTTP認證才能訪問的內容,輸出是自動不可以緩存的; 
4) no-cache — 強制每次請求直接發送給源服務器,而不經過本地緩存版本的校驗。這對於需要確認認證應用很有用(可以和public結合使用),或者嚴格要求使用最新數據的應用(不惜犧牲使用緩存的所有好處); 
5) no-store — 強制緩存在任何情況下都不要保留任何副本 
6) must-revalidate — 告訴緩存必須遵循所有你給予副本的新鮮度的,HTTP允許緩存在某些特定情況下返回過期數據,指定了這個屬性,你高速緩存,你希望嚴格的遵循你的規則。 
7) proxy-revalidate — 和 must-revalidate類似,除了他只對緩存代理服務器起作用 
舉例:
Cache-Control: max-age=3600, must-revalidate

很顯然Cache-control可以提供比Expires更靈活的緩存控制,而且它不需要依賴於服務器時間。
在Asp.Net中微軟把對Cache-control屬性的設置封裝到了HttpCachePolicy類中,我們可以通過Response.Cache來調用以下方法來做到對Cache-Control Http頭值的控制:
Response.CacheControl;
Response.Cache.SetNoStore
Response.Cache.SetMaxAge
Response.Cache.SetProxyMaxAge
Response.Cache.SetRevalidation
            
3. Last-Modified/If-Modified-Since 
這兩個Http頭是一對,前者表示某個地址的最近更新時間,是服務器端響應給客戶端的;而后者是客戶端瀏覽器發送給服務器的,告訴web服務器客戶端有一個最后更改時間為什么時間的緩存,服務器端接收到If-Modified-Since頭后則判斷客戶端緩存的這份url地址的緩存是否是最新的,如果是最新的則服務器端直接給客戶端返回HttpStatus 304,意思是說這個內容在你上次請求之后沒有變化過,你直接用緩存就可以了;如果服務器發現url的最后更新時間比If-Modified-Since的值要新,則會輸出新的內容。

同樣微軟也為我們做了服務器端設置的封裝,我們可以這樣調用
Response.Cache.SetLastModified(DateTime)
Response.Cache.SetLastModifiedFromFileDependencies()

如果有更復雜的需求就需要自己處理了。

4. ETag/If-None-Match
ETag和Last-Modified類似,不過他發送的是一個字符串來標示url的版本,如果url變了則此標示也跟着變化,在瀏覽器發送If-None-Match時告訴瀏覽器內容已經變了,或者沒變可以使用緩存。

Iis會自動給靜態文件加上Etag,在文件發生改變時重新生成一個Etag,這樣對於一個網站中的n多個靜態文件如:樣式表,小圖片等,客戶端只下載一次就夠了,可以減輕負載。

在Asp.Net中我們可以用以下兩個方法來設置
Response.Cache.SetETag(string)
Response.Cache.SetETagFromFileDependencies()

盡管微軟為我們做了很多封裝,但是我們還是需要詳細的了解之后才可以用好這幾個Http頭。

轉自:http://hi.baidu.com/heelenyc/item/3e96013d89f98d09ceb9fee6

     http://www.cnblogs.com/yukaizhao/archive/2009/07/10/http_header_cache.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM