2009-10-18 87 views
13

我正在使用PHP腳本來提供文件。 我希望能夠在我的http響應中發送一個304未修改的標頭,如果該文件自從客戶端上次下載以來沒有更改過。這似乎是Apache(和大多數其他Web服務器)中的一項功能,但我不知道如何通過PHP實現。304:未修改和前端緩存

我聽說過使用$_SERVER['HTTP_IF_MODIFIED_SINCE'],但這個變量似乎沒有出現在我的$_SERVER超級數組中。

我的問題不是如何返回一個304標題,但如何知道應該返回一個。我的$_SERVER['HTTP_IF_MODIFIED_SINCE']沒有設置。這是我.htaccess文件的內容:

ExpiresActive On 
ExpiresByType image/jpeg "modification plus 1 month" 
ExpiresByType image/png "modification plus 1 month" 
ExpiresByType image/gif "modification plus 1 month" 
Header append Cache-Control: "must-revalidate" 


<IfModule mod_rewrite.c> 
    RewriteEngine On 
    RewriteCond $1 !^(controller\.php) 
    RewriteRule (.*\.jpg|.*\.png|.*\.gif) controller.php/$1 
</IfModule> 

HTTP_IF_MODIFIED_SINCE仍然沒有出現在$_SERVER超級陣列英寸

回答

26

HTTP_IF_MODIFIED_SINCE是正確的做法。如果你沒有得到它,請檢查Apache是​​否已啓用mod_expiresmod_headers並正常工作。從a comment on PHP.net借用:

$last_modified_time = filemtime($file); 
$etag = md5_file($file); 
// always send headers 
header("Last-Modified: ".gmdate("D, d M Y H:i:s", $last_modified_time)." GMT"); 
header("Etag: $etag"); 
// exit if not modified 
if (@strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $last_modified_time || 
    @trim($_SERVER['HTTP_IF_NONE_MATCH']) == $etag) { 
    header("HTTP/1.1 304 Not Modified"); 
    exit; 
} 

// output data 
+1

我已經看到了這樣做,但$ _SERVER ['HTTP_IF_MODIFIED_SINCE']對我來說總是空的... – 2009-10-18 01:48:29

+0

檢查我最近的編輯 - 我遺漏了一個重要的Apache配置信息。 – 2009-10-18 01:48:58

+0

試圖根據http://www.webmasterworld.com/forum23/2300.htm修改我的htaccess.txt文件,但沒有去。有任何想法嗎? – 2009-10-18 02:29:10

0

$_SERVER['HTTP_IF_MODIFIED_SINCE']通常是空的時候register_globals關閉。

檢查是否是這樣的話,如果是這樣嘗試getenv('HTTP_IF_MODIFIED_SINCE')

1

This article將回答你關於緩存所​​有問題

我發現,添加

RewriteRule .* - [E=HTTP_IF_MODIFIED_SINCE:%{HTTP:If-Modified-Since}] 
RewriteRule .* - [E=HTTP_IF_NONE_MATCH:%{HTTP:If-None-Match}] 

要我htaccess文件的底部(低於一切重寫)工作。

0

也有一些其他的參數來檢查。在我來說,我沒有過這兩個頭:

$_SERVER['HTTP_IF_NONE_MATCH'] && $_SERVER['HTTP_IF_MODIFIED_SINCE'] 

被要求返回正確的304頭,因爲我的系統時鐘是有點晚了,它會解釋這些網頁過期在未來,那麼不是在所有

發送這些值還要檢查它是Apache返回頭,或者至少覆蓋到更大的價值

Cache-Control: max-age=3600 

它並不會像以前發頭如果

Last-Modified previous sent header < (NOW - 3600) 

所以在我的情況我已經設置這個非常方便的功能 function lastModified($file){ $x=filemtime($file); while($x>time())$x-=86000;}#reduce by one day if touched in future date $date=gmdate('D, j M Y H:i:s',$x).' GMT'; header('Cache-Control: max-age=86000',1); if($_SERVER['HTTP_IF_NONE_MATCH'] == $x || $_SERVER['HTTP_IF_MODIFIED_SINCE']==$date){ header('HTTP/1.1 304 Not Modified',1,304);die;} header('Etag: '.$x,1);header('Last-Modified: '.$date,1); }

0

我有這個問題,它原來僅僅是,我已Firebug開放。這在默認打勾的網絡選項卡「禁用瀏覽器緩存」下有一個選項。 Chrome的開發人員工具中有一個類似的選項,即菜單欄下方的一個勾選框。

解開這些選項導致瀏覽器正確發送HTTP_IF_MODIFIED_SINCE並且一切正常(甚至在Firebug或Chrome開發工具打開的情況下)。