2009-10-18 13 views
13

Używam skryptu PHP do serwowania plików. Chciałbym móc odesłać niezmodyfikowany nagłówek 304 w mojej odpowiedzi http, jeśli plik nie zmienił się od ostatniego pobrania przez klienta. Wydaje się, że jest to funkcja w Apache (i większości innych serwerach internetowych), ale nie mam pojęcia, jak można to zaimplementować za pomocą PHP.304: Nie zmodyfikowane i buforowanie z przodu

Słyszałem o użyciu $_SERVER['HTTP_IF_MODIFIED_SINCE'], ale ta zmienna nie pojawia się w mojej super tablicy $_SERVER.

Moje pytanie nie brzmi, jak zwrócić nagłówek 304, ale jak się dowiedzieć, że należy go zwrócić.


Edycja: Problem polega na tym, że mój $_SERVER['HTTP_IF_MODIFIED_SINCE'] nie jest ustawiony. Jest to zawartość mojego pliku .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 nadal nie pojawia się w super tablicy $_SERVER.

Odpowiedz

26

HTTP_IF_MODIFIED_SINCE to właściwy sposób na zrobienie tego. Jeśli go nie otrzymujesz, sprawdź, czy Apache ma włączone i działa poprawnie mod_expires i mod_headers. Zapożyczone z 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

Widziałem ten sposób robienia tego, ale $ _SERVER ['HTTP_IF_MODIFIED_SINCE'] jest zawsze puste dla mnie ... –

+0

Sprawdź moją ostatnią edycję - Opuściłem kawałek ważnych informacji konfiguracyjnych Apache. –

+0

Próbowałem zmodyfikować mój plik htaccess.txt zgodnie z adresem http://www.webmasterworld.com/forum23/2300.htm, ale nie ma go. Jakieś pomysły? –

0

$_SERVER['HTTP_IF_MODIFIED_SINCE'] jest zazwyczaj pusta, kiedy register_globals jest wyłączony.

Sprawdź, czy to przypadek, a jeśli tak, spróbuj getenv('HTTP_IF_MODIFIED_SINCE')

1

This article odpowiedzą na wszystkie pytania dotyczące buforowania

stwierdziliśmy, że dodanie

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

do dna mojego pliku .htaccess (poniżej wszystkich przepisań) działało.

0

Istnieją również inne parametry, aby sprawdzić .. w moim przypadku nie miał obu tych nagłówków:

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

które są wymagane, aby powrócić do właściwego nagłówka 304, jako mojego zegara systemowego było trochę późno, to będzie interpretować te strony jako wygasające w przyszłości, to nie wysyłając te wartości w ogóle

sprawdzić również, że nagłówek, który jest zwracany przez apache, lub przynajmniej zastąpić go do większej wartości

Cache-Control: max-age=3600 

Ponieważ nie wyśle ​​wcześniejsze nagłówki jeśli

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

Więc w moim przypadku mam ustawić ten dość poręczny funkcji 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

miałem ten problem i okazało się być po prostu, że miałem Firebug otwarty. Ta opcja jest dostępna na karcie Sieć "Wyłącz pamięć podręczną przeglądarki", która jest zaznaczona domyślnie. Jest podobna opcja w narzędziach programistycznych Chrome, jednym z pól wyboru na pasku pod paskiem menu.

Nieodłączenie tych opcji spowodowało, że przeglądarka prawidłowo wysłała HTTP_IF_MODIFIED_SINCE i wszystko działało dobrze (mimo otwartego narzędzia Firebug lub Chrome Dev Tools).

Powiązane problemy