web-dev-qa-db-ja.com

CloudFlareがIf-Modified-Sinceヘッダーを送信しない

必要に応じて、コンテンツに304 Not Modified応答を提供することにより、サーバーの負荷を軽減しようとしています。 CloudFlareは私の仲介人なので、キャッシュされたページの有効期限が切れるたびにIf-Modified-Sinceヘッダーを送信する必要がありますか?

クライアント側でこれらの応答を受信して​​います:

  • CF-Cache-Status: MISS最初のページの読み込み時
  • CF-Cache-Status: Hitページのリロードは20秒間
  • CF-Cache-Status: EXPIRED 20秒後のページのリロード

期限切れのリクエストはサーバーに転送されますが、If-Modified-Sinceヘッダーは含まれていません。これを機能させるにはどうすればよいですか?

<?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>');

更新:ここに作業コードがあります

<?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

私の理解と経験から、おそらくCDNキャッシングの仕組みを誤解しているように思えます。

  • あなたが与えた例から、CDNはファイルが期限切れであり、とにかく再フェッチする必要があることをすでに伝えているので、ファイルが最後に変更されたときあなたのウェブサーバーに尋ねません。

  • Webブラウザーは、ページ/リソースが以前にWebブラウザーによってキャッシュされており、最初に要求されたときにIf-Modified-Sinceヘッダーが付いていた場合にのみLast-Modifiedヘッダーを送信します。

  • あなたの例のようにE-Tagヘッダーを送信すると、これはブラウザー間で一貫性がなく、ブラウザーからの後続のリクエストでIf-None-Matchの代わりにIf-Modified-Sinceヘッダーになる場合があります。

ただし、CDNは通常、プロキシサーバーまたはWebアクセラレータに似たいくつかの点で、Webブラウザと同じように動作しません。

  • CDNキャッシュページの有効期限が切れている場合、次にWebブラウザーから要求されたときに、CDNはWebサーバーから新しいコピーをフェッチし、CDNキャッシュコピーを更新して、リソースをWebブラウザーに戻します。 HTTPレスポンス。通常、If-Modified-SinceヘッダーがWebサーバーに到達する必要はありませんが、私のテストではCloudFlareがこのヘッダーを引き続き発行することが明らかになりました。

  • サーバーの負荷を減らすには、s-maxageディレクティブを使用して、CDNがWebブラウザーで既に実行されているレベルを超えるキャッシュレベルを提供できるようにします。 max-ageヘッダーのCache-Controlディレクティブに似ていますが、これは他のヘッダーよりも優先してCDN(および同様のサービス)によって監視され、max-ageはWebブラウザークライアントによって監視されます。

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

    このヘッダーを使用する場合、Webブラウザーからの最初の要求はCDN MISSになりますが、WebブラウザーとCDNの両方でキャッシュされます。最初の20秒後、Webブラウザーのキャッシュコピーは期限切れになります。その後、ページがリロードされると、CDNはHTTP応答でCDNキャッシュからWebブラウザにコピーを返すさらに40秒間HITを実行します。最初の要求から60秒後にCDNキャッシュが期限切れになり、後続の要求はCDN EXPIREDになりますが、それ以外はCDNと同じように扱われますMISS取得あなたのウェブサーバーからの新しいコピー、そしてループシーケンスが続くでしょう。

    1時間のWebブラウザーキャッシングと6時間のCDNキャッシングのための、より本番対応のヘッダーは次のようになります。

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

    6時間のCDNの有効期限よりも早く更新を公開する必要がある場合は、CDNにWebベースのコントロールパネルから新しいキャッシュを取得するように常に指示できます。このヘッダーを使用すると、CDNがWebトラフィックの大部分を処理する間、各リソースはWebサーバーから1日に4回しか取得されません。


2014年11月11日UTC 12時45分45秒編集:

また、影響を与える可能性のある副次的な注意点として、PHPコードに問題があり、それが正しい操作に影響している可能性があります-ETagおよびExpires =コードのヘッダー行をテストすると、次のヘッダーが生成されます。

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

代わりに、テストでこれらの行を試して、送信済みヘッダーも表示できるようにしてください。

<?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

304 Not Modifiedヘッダーにはサーバーへのリクエストが必要であることに注意してください。

304 Not Modifiedヘッダーを送信するのは適切ではありません。キャッシュの有効期限ヘッダーを送信するのが最も望ましいので、ブラウザーはリソースを再度要求することさえしません。もちろん、静的リソース(画像、スクリプトなど)にのみ関連します。

私の経験では、CloudFlareは静的リソースのLast-Modifiedヘッダーのみを送信します。

CloudFlareのページURLを見て、ページ(つまり、画像、スクリプトなどではない)にデフォルト以外のカスタムキャッシュ値を指定することができますか?

0
Emil Rasmussen