142

httpキャッシングを使用しようとしています。私のコントローラーでは、次のように応答を設定しています。

$response->setPublic();
$response->setMaxAge(120);
$response->setSharedMaxAge(120);
$response->setLastModified($lastModifiedAt);

開発モード

開発環境では、最初の応答は次のヘッダーを持つ 200 です。

cache-control:max-age=120, public, s-maxage=120
last-modified:Wed, 29 Feb 2012 19:00:00 GMT

次の 2 分間、すべての応答は次のヘッダーを持つ 304 です。

cache-control:max-age=120, public, s-maxage=120

これは基本的に私が期待していることです。

製品モード

prod モードの応答ヘッダーは異なります。app.php では、AppCache でカーネルをラップしていることに注意してください。

最初の応答は、次のヘッダーを持つ 200 です。

cache-control:must-revalidate, no-cache, private
last-modified:Thu, 01 Mar 2012 11:17:35 GMT

したがって、これはプライベートなキャッシュなしの応答です。

次のすべてのリクエストは、私が期待するものとほぼ同じです。次のヘッダーを持つ 304:

cache-control:max-age=120, public, s-maxage=120

私はそれについて心配する必要がありますか?それは期待される動作ですか?

その前に Varnish または Akamai サーバーを配置するとどうなりますか?

少しデバッグを行ったところ、最後に変更されたヘッダーのために応答がプライベートであることがわかりました。HttpCache カーネルは EsiResponseCacheStrategyを使用して、キャッシュされた応答を更新します ( HttpCache::handle()メソッド)。

if (HttpKernelInterface::MASTER_REQUEST === $type) {
    $this->esiCacheStrategy->update($response);
}

EsiResponseCacheStrategyは、 Last-Response または ETag ( EsiResponseCacheStrategy::add()メソッド)を使用する場合、応答をキャッシュ不可にします。

if ($response->isValidateable()) {
    $this->cacheable = false;
} else {
    // ... 
}

Response::isValidateable()は、Last-Response または ETag ヘッダーが存在する場合に true を返します。

その結果、Cache-Control ヘッダーが上書きされます( EsiResponseCacheStrategy::update()メソッド)。

if (!$this->cacheable) {
    $response->headers->set('Cache-Control', 'no-cache, must-revalidate');

    return;
}

Symfony2 ユーザー グループでこの質問をしましたが、今のところ回答がありません: https://groups.google.com/d/topic/symfony2/6lpln11POq8/discussion

アップデート。

元のコードにアクセスできなくなったので、最新の Symfony standard edition でシナリオを再現しようとしました。

応答ヘッダーはより一貫したものになりましたが、それでも間違っているようです。

応答にヘッダーを設定するとすぐにLast-Modified、ブラウザーによって作成された最初の応答には次のようになります。

Cache-Control:must-revalidate, no-cache, private

2 番目の応答には次のものが期待されます。

Cache-Control:max-age=120, public, s-maxage=120

If-Modified-Sinceヘッダーを送信しないと、すべてのリクエストが返されますmust-revalidate, no-cache, private

リクエストがどの環境で行われたprodかは関係ありません。dev

4

2 に答える 2

9

私は同じ問題に直面しました。CDN に「パブリック」ヘッダーを指定する必要がありました。デフォルトでは、prod モードでゲートウェイ キャッシングが有効になっている場合、プライベートで 200 OK が返され、nocache はヘッダーを検証する必要があります。

私はこの方法で問題を解決しました。

app.php で、ユーザーに応答を送信する ($respond->send) 前に、キャッシュ コントロール ヘッダーを空白に上書きし、キャッシュ ヘッダーを public および max age(some value) に設定しました。

// app.php のコード スニペット

    $response = $kernel->handle($request);
    $response->headers->set('Cache-Control', '');
    $response->setPublic();
    $response->setMaxAge(86400);
    $response->send();        
于 2014-02-09T09:02:27.850 に答える