PHP與瀏覽器緩衝

來源:互聯網
上載者:User
我們往往在伺服器上對緩衝設定進行各種最佳化方案,但是我們卻很少注意到用戶端緩衝,準確的說是瀏覽器的緩衝機制。


其實每種瀏覽器都有緩衝策略,會暫時將每一個瀏覽過的檔案快取在一個特殊的檔案夾裡。我們就可以在使用者重複提交頁面請求的時候,告訴使用者這個頁 面沒有改變,可以調用緩衝。 那我們怎麼知道使用者有沒有這個頁面的快取資料呢? 其實瀏覽器在發送請求的時候會先發送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 代碼複製到剪貼簿
  • if ($_SERVER["HTTP_IF_NONE_MATCH"] == "claymorephp.com")
  • {
  •     header('Etag:'.'zhaiyun.com',true,304);
  •     exit();
  • }
  • else {
  •     header('Etag:'."claymorephp.com");
  • }
  • 你還可以稍微改一下:
  • $expires=date("Ymd"); //一天后緩衝到期
  • if ($_SERVER["HTTP_IF_NONE_MATCH"] == $expires)
  • {
  •     header('Etag:'.$expires,true,304);
  •     exit();
  • }
  • else {
  •     header('Etag:'.$expires);
  • }

if ($_SERVER["HTTP_IF_NONE_MATCH"] == "claymorephp.com") { header('Etag:'.'zhaiyun.com',true,304); exit(); } else { header('Etag:'."claymorephp.com"); } 你還可以稍微改一下: $expires=date("Ymd"); //一天后緩衝到期 if ($_SERVER["HTTP_IF_NONE_MATCH"]
== $expires) { header('Etag:'.$expires,true,304); exit(); } else { header('Etag:'.$expires); }
另外,當GZIP和ETAG同時使用時有時會出問題,就是ETAG沒有值,這個問題是普遍存在的,我暫時沒有找到相關的原因,網上搜了一會,普遍的人稱之為BUG。


基於以上原因,關於PHPBLOG的用戶端緩衝是以下來處理的(同時對HTTP_IF_NONE_MATCH和HTTP_IF_MODIFIED_SINCE進行判斷):PHP 代碼複製到剪貼簿
  •     if($_SERVER['HTTP_IF_NONE_MATCH'])
  •     {
  •         if($_SERVER['HTTP_IF_NONE_MATCH'] == 'phpblog')
  •         {
  •             header('Etag:phpblog',true,304);//控制瀏覽器緩衝
  •             $_SESSION['time_end']=microtime(true);
  •             exit();
  •         }
  •     }
  •     else if($_SERVER['HTTP_IF_MODIFIED_SINCE'])//eg:Sun, 02 Nov 2008 07:08:25 GMT; length=35849
  •     {
  •         $array=explode(' ',$_SERVER['HTTP_IF_MODIFIED_SINCE']);
  •         $gmday=$array[1];
  •         $month_array=array(
  •         "Jan"=>"01",
  •         "Feb"=>"02",
  •         "Mar"=>"03",
  •         "Apr"=>"04",
  •         "May"=>"05",
  •         "Jun"=>"06",
  •         "Jul"=>"07",
  •         "Aug"=>"08",
  •         "Sep"=>"09",
  •         "Oct"=>"10",
  •         "Nov"=>"11",
  •         "Dec"=>"12");
  •         $gmmonth=$month_array[$array[2]];
  •         $gmyear=$array[3];
  •         $array=explode(':',$array[4]);
  •         $gmtimestamp=gmmktime($array[0],$array[1],$array[2],$gmmonth,$gmday,$gmyear);
  •         if(gmmktime()-$gmtimestamp<$config_client_cache_time*60*60)
  •         {
  •             header('Etag:phpblog',true,304);//控制瀏覽器緩衝
  •             $_SESSION['time_end']=microtime(true);
  •             exit();
  •         }
  •     }

if($_SERVER['HTTP_IF_NONE_MATCH']) { if($_SERVER['HTTP_IF_NONE_MATCH'] == 'phpblog') { header('Etag:phpblog',true,304);//控制瀏覽器緩衝 $_SESSION['time_end']=microtime(true); exit(); } } else if($_SERVER['HTTP_IF_MODIFIED_SINCE'])//eg:Sun,
02 Nov 2008 07:08:25 GMT; length=35849 { $array=explode(' ',$_SERVER['HTTP_IF_MODIFIED_SINCE']); $gmday=$array[1]; $month_array=array( "Jan"=>"01", "Feb"=>"02", "Mar"=>"03", "Apr"=>"04", "May"=>"05", "Jun"=>"06", "Jul"=>"07", "Aug"=>"08", "Sep"=>"09", "Oct"=>"10",
"Nov"=>"11", "Dec"=>"12"); $gmmonth=$month_array[$array[2]]; $gmyear=$array[3]; $array=explode(':',$array[4]); $gmtimestamp=gmmktime($array[0],$array[1],$array[2],$gmmonth,$gmday,$gmyear); if(gmmktime()-$gmtimestamp<$config_client_cache_time*60*60) { header('Etag:phpblog',true,304);//控制瀏覽器緩衝
$_SESSION['time_end']=microtime(true); exit(); } } 緩衝的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');//返回最後修改時間
  •         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');//返回標識,用於標識上次的確訪問過(瀏覽器中存在緩衝)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.