我們往往在伺服器上對快取設定進行各種優化方案,但是我們卻很少注意到客戶端快取,準確的說是瀏覽器的快取機制。
其實每種瀏覽器都有快取策略,會暫時將每乙個瀏覽過的檔案快取在乙個特殊的資料夾裡。我們就可以在使用者重複提交頁面請求的時候,告訴使用者這個頁 面沒有改變,可以呼叫快取。 那我們怎麼知道使用者有沒有這個頁面的快取資料呢? 其實瀏覽器在傳送請求的時候會先傳送http頭,一般象這樣:
date: sun, 30 jul 2006 09:18:11 gmt
content-type: image/gif
last-modified: wed, 19 jul 2006 07:40:06 gmt
etag: "8c55da8d6abc61:2327"
content-length: 14757
其中last-modified: wed, 19 jul 2006 07:40:06 gmt
etag: "8c55da8d6abc61:2327"
就是有關頁面的快取資訊的。然後如果伺服器返回的響應**不是http 200 (ok),而是 304的話,瀏覽器就會從快取中讀取資料。
//告訴客戶端瀏覽器不使用快取,http 1.1 協議
header("cache-control: no-cache, must-revalidate");
//告訴客戶端瀏覽器不使用快取,相容http 1.0 協議
header("pragma: no-cache");
根據這個原理,可以用在不經常更新或者需要經常重新整理的頁面,可以大大減輕伺服器的負擔,因為它如果發現客戶端有快取,就向客戶端傳送乙個304響應,然後停止程式的執行。
瀏覽器發出的請求中包含if-modified-since和if-none-match 兩個引數,第乙個表示詢問資料的最後修改時間是否是thu,19 jun 2008 16:24:01 gmt 然後伺服器就會檢查資料的最後修改時間,如果是該時間則返回狀態碼304(表示沒有修改),此時當瀏覽器收到狀態碼是304時就不會**資料而是從本地緩 存中呼叫。然而只有本地快取中存在著該請求資源的資料時瀏覽器才會傳送if-modified-since引數並且其值為上一次伺服器所返回的last- modified的值(並不是所有的伺服器都支援if-modified-since和if-none-match );if-none-match的功能也類似,它是由伺服器返回的etag的值生成的,可以是任意值,因為其作用僅僅是使伺服器檢查資料的修改時間然後返 回而已,只要不為none(預設值)或不為空其它的都可以。
所以我們可以在**的最前部分設定返回給瀏覽的etag為某個值,然後在這個資源被第二次請求的時候就會附帶著乙個if-none-match 參 數,通過核實其值確實為所發出的etag值時就可以指定伺服器返回為304然後強行退出程式就行了,if-modified-since也是一樣的做法這 裡就只給出etag方法的php版(last-modified版的太常見了如設定快取超時等等):
php **複製到剪貼簿
複製** **如下:
你還可以稍微改一下:
$expires=date("ymd"); //一天後快取過期
if ($_server["http_if_none_match"] == "claymorephp.com") else 你還可以稍微改一下: $expires=date("ymd"); //一天後快取過期 if ($_server["http_if_none_match"] == $expires) else
另外,當gzip和etag同時使用時有時會出問題,就是etag沒有值,這個問題是普遍存在的,我暫時沒有找到相關的原因,網上搜了一會,普遍的人稱之為bug。
基於以上原因,關於phpblog的客戶端快取是以下來處理的(同時對http_if_none_match和http_if_modified_since進行判斷):
php **複製到剪貼簿
複製** **如下:
快取的header是這樣來傳送的:
php **複製到剪貼簿
複製** **如下:
$client_cache_time=$config_client_cache_time*60*60;//單位 - 秒
header('cache-control: public, max-age='.$client_cache_time);
header('expires: '.gmdate('d, d m y h:i:s',time()+$client_cache_time).' gmt');//設定頁面快取時間
header('last-modified: '.gmdate('d, d m y h:i:s',time()).' gmt');//返回最後修改時間
&nbwww.cppcns.comsp; header('pragma: public');
header('etag:phpblog');//返回標識,用於標識上次的確訪問過(瀏覽器中存在快取)
$client_cache_time=$config_client_cache_time*60*60;//單位 - 秒 header('cache-control: public, max-age='.$client_cache_time); header('expires: '.gmdate('d, d m y h:i:s',time()+$client_cache_time).' gmt');//設定頁面快取時間 header('last-modified: '.gmdate('d, d m y h:i:s',time()).' gmt');//返回最後修改時間 header('pragma: public'); header('etag:phpblog');//返回標識,用於標識上次的確訪問過(瀏覽器中存在快取)
本文標題: 深入php與瀏覽器快取的分析
本文位址:
php 瀏覽器 快取,深入PHP與瀏覽器快取的分析
我們往往在伺服器上對快取設定進行各種優化方案,但是我們卻很少注意到客戶端快取,準確的說是瀏覽器的快取機制。其實每種瀏覽器都有快取策略,會暫時將每乙個瀏覽過的檔案快取在乙個特殊的資料夾裡。我們就可以在使用者重複提交頁面請求的時候,告訴使用者這個頁 面沒有改變,可以呼叫快取。那我們怎麼知道使用者有沒有這...
PHP與瀏覽器快取
我們往往在伺服器上對快取設定進行各種優化方案,但是我們卻很少注意到客戶端快取,準確的說是瀏覽器的快取機制。其實每種瀏覽器都有快取策略,會暫時將每乙個瀏覽過的檔案快取在乙個特殊的資料夾裡。我們就可以在使用者重複提交頁面請求的時候,告訴使用者這個頁 面沒有改變,可以呼叫快取。那我們怎麼知道使用者有沒有這...
php 瀏覽器快取
瀏覽器快取動態內容,快取的內容在瀏覽器本地,而內容由web伺服器生成,任何一方都不可能完成這一系列過程,他們之間有一種溝通機制,這就是快取協商.如何協商 如用ie瀏覽器訪問這個頁面時,返回狀態碼200,連續多次重新整理這個頁面,這個頁面並沒有使用本地快取,也沒有向伺服器作出任何表示.開啟ie的和這個...