wake-up-neo.com

CloudFlare sendet keine If-Modified-Since-Header

Ich versuche, die Serverlast zu reduzieren, indem ich 304 Not Modified Antworten für den Inhalt gebe, wo dies angebracht ist. CloudFlare ist mein Mann in der Mitte, daher sollten sie If-Modified-Since Header senden, wenn eine zwischengespeicherte Seite abgelaufen ist, oder?

Ich erhalte auf Kundenseite die folgenden Antworten:

  • CF-Cache-Status: MISS beim Laden der ersten Seite
  • CF-Cache-Status: Hit auf der Seite wird 20 Sekunden lang neu geladen
  • CF-Cache-Status: EXPIRED auf Seite nach 20 Sekunden neu laden

Die abgelaufene Anforderung wird an meinen Server weitergeleitet, enthält jedoch keinen If-Modified-Since -Header. Wie kann ich das zum Laufen bringen?

<?php
$now = time();
header( "ETag: W/\"$now\"" );
header( 'Expires: '.gmdate('D, d M Y H:i:s \G\M\T', $now + 20) );

header( 'Last-Modified: '.time() );
header( 'Cache-Control: public, max-age=20' );

print('<pre>');
print_r($_SERVER);
print('</pre>');

UPDATE: Hier ist der Arbeitscode

<?php

if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
    // $date = $_SERVER['HTTP_IF_MODIFIED_SINCE'];
    header("HTTP/1.1 304 Not Modified");
    exit();
}

$format = 'D, d M Y H:i:s \G\M\T';
$now = time();

$date = gmdate($format, $now);
header('Date: '.$date);
header('Last-Modified: '.$date);

$date = gmdate($format, $now+30);
header('Expires: '.$date);

header('Cache-Control: public, max-age=30');

print('<pre>'); 
print_r($_SERVER); 
print('</pre>');
3
skibulk

Nach meinem Verständnis und meiner Erfahrung scheinen Sie vielleicht falsch verstanden zu haben, wie CDN-Caching funktioniert:

  • In dem Beispiel, das Sie angegeben haben, fragte das CDN Ihren Webserver nicht, wann die Datei zuletzt geändert wurde, da Sie ihm bereits mitgeteilt haben, dass die Datei abgelaufen ist und daher ohnehin erneut abgerufen werden muss.

  • Webbrowser senden nur dann einen If-Modified-Since -Header, wenn die Seite/Ressource zuvor vom Webbrowser zwischengespeichert wurde und bei der ersten Anforderung einen Last-Modified -Header enthielt.

  • Wenn Sie einen E-Tag -Header wie in Ihrem Beispiel senden, ist die Behandlung dieses Headers über die Browser hinweg nicht konsistent, und Sie erhalten möglicherweise in der nachfolgenden Anforderung des Browsers einen If-None-Match -Header anstelle eines If-Modified-Since.

CDNs verhalten sich jedoch in der Regel nicht wie Webbrowser, sondern ähneln in gewisser Weise Proxyservern oder Webbeschleunigern:

  • Wenn eine im CDN-Cache gespeicherte Seite abgelaufen ist, ruft der CDN auf Anforderung eines Webbrowsers einfach eine neue Kopie vom Webserver ab, aktualisiert die im CDN-Cache gespeicherte Kopie und leitet die Ressource an den Webbrowser im weiter HTTP-Antwort. Normalerweise ist es nicht erforderlich, dass If-Modified-Since Header Ihren Webserver erreichen, obwohl meine Tests ergeben haben, dass CloudFlare diesen Header weiterhin ausgibt.

  • Um die Serverauslastung zu verringern, aktivieren Sie das CDN mit der Anweisung s-maxage, um eine höhere Cachestufe als die von den Webbrowsern bereits vorgenommenen bereitzustellen. Ähnlich wie die Anweisung max-age in Ihrem Header Cache-Control, wird diese jedoch von CDNs (und ähnlichen Diensten) vor allen anderen Headern beachtet, während die Anweisung max-age von der Webbrowser-Clients.

    header( 'Cache-Control: public, max-age=20, s-maxage=60' );

    Wenn Sie diesen Header verwenden, ist die erste Anforderung von einem Webbrowser eine CDN MISS, die jedoch sowohl im Webbrowser als auch im CDN zwischengespeichert wird. Nach den ersten 20 Sekunden läuft die zwischengespeicherte Kopie des Webbrowsers ab. Wenn die Seite dann erneut geladen wird, wird das CDN für weitere 40 Sekunden HIT eine Kopie aus dem CDN-Cache an den Webbrowser in der HTTP-Antwort zurücksenden. Sechzig Sekunden nach der ersten Anforderung ist der CDN-Cache abgelaufen und eine nachfolgende Anforderung ist eine CDN EXPIRED, wird aber ansonsten genauso behandelt wie eine CDN MISS eine neue Kopie von Ihrem Web-Server, und so würde die Loop-Sequenz fortgesetzt.

    Ein produktionsfähigerer Header für das 1-stündige Webbrowser-Caching und das 6-stündige CDN-Caching könnte folgendermaßen aussehen:

    header( 'Cache-Control: public, max-age=3600, s-maxage=21600' );

    Wenn Sie jemals ein Update schneller als nach Ablauf der 6-Stunden-CDN veröffentlichen mussten, können Sie das CDN jederzeit anweisen, einen neuen Cache aus dem webbasierten Steuerungsfeld zu entnehmen. Mit diesem Header wird jede Ressource nur viermal am Tag von Ihrem Webserver abgerufen, während das CDN den gesamten Datenverkehr im Web abwickelt.


Bearbeitet am 11. November 2014 um 12:45 Uhr UTC-0:

Auf eine Nebenbemerkung, die sich ebenfalls auswirken könnte, gibt es Probleme mit Ihrem PHP Code, die sich möglicherweise auf den korrekten Betrieb auswirken - Ihr ETag und Expires = Header-Codezeilen, wenn ich sie teste, erzeugen die folgenden Header:

ETag: W/""
Expires: Thu, 01 Jan 1970 00:00:20 GMT

Probieren Sie stattdessen diese Zeilen in Ihrem Test aus, damit Sie auch Ihre gesendeten Header sehen können:

<?php
$iClientCacheSecs = 20;
$iProxyCacheSecs = 60;
$dtNow = time();
$dtExpires = strtotime( sprintf( '+%s seconds', $iClientCacheSecs ));
$aHeaders = array();
$aHeaders[] = 'ETag: ' . $dtNow;
$aHeaders[] = 'Expires: ' . date( 'r', $dtExpires );
$aHeaders[] = 'Last-Modified: ' . date( 'r', $dtNow );
$aHeaders[] = sprintf( 'Cache-Control: public, max-age=%s, s-maxage=%s',
  $iClientCacheSecs, $iProxyCacheSecs );
foreach( $aHeaders as $sHeader ) header( $sHeader );
echo( 'Now: ' . date( 'r', $dtNow ) . '<br />' );
foreach( $aHeaders as $sHeader ) echo( $sHeader . '<br />' );
echo( '<hr />' );
foreach( $_SERVER as $sParam => $sValue ) {
  if(( strpos( $sParam, 'HTTP_CF' )) !== false ) 
    echo( $sParam . ': ' . $sValue . '<br />' );
  if(( strpos( $sParam, 'HTTP_IF' )) !== false ) 
    echo( $sParam . ': ' . $sValue . '<br />' );
}
3
richhallstoke

Beachten Sie, dass für einen nicht geänderten 304-Header weiterhin eine Anforderung erforderlich ist, die an Ihren Server weitergeleitet wird.

Sie möchten 304 nicht geänderte Header nicht ordnungsgemäß senden. Am häufigsten möchten Sie einen Cache-Expire-Header senden, damit der Browser nicht einmal versucht, die Ressourcen erneut anzufordern. Das gilt natürlich nur für statische Ressourcen (Bilder, Skripte etc.).

Nach meiner Erfahrung sendet CloudFlare nur Zuletzt geänderte Header für statische Ressourcen.

Vielleicht möchten Sie einen Blick auf die Seiten-URLs von CloudFlare werfen und Ihren Seiten (d. H. Nicht Bildern, Skripten usw.) einen anderen benutzerdefinierten Caching-Wert als den Standardwert zuweisen?

0
Emil Rasmussen