如果第一个响应是AppCache(Symfony2)的私有,这样可以吗?

时间:2012-03-05 14:13:05

标签: caching symfony cache-control http-caching

我正在尝试使用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

这基本上就是我所期望的。

产品模式

在产品模式下,响应标头不同。请注意,在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内核uses EsiResponseCacheStrategy更新缓存的响应(HttpCache::handle()方法)。

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

EsiResponseCacheStrategy turns a response into non cacheable如果它使用Last-Response或ETag(EsiResponseCacheStrategy::add()方法):

if ($response->isValidateable()) {
    $this->cacheable = false;
} else {
    // ... 
}
如果存在Last-Response或ETag标头,

Response::isValidateable()将返回true。

结果是overwriting the Cache-Control headerEsiResponseCacheStrategy::update()方法):

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

    return;
}

我在Symfony2用户组上问了这个问题,但到目前为止我没有得到答案:https://groups.google.com/d/topic/symfony2/6lpln11POq8/discussion

更新

由于我无法访问原始代码,因此尝试reproduce the scenario with the latest Symfony standard edition

响应标头现在更加一致,但似乎仍然是错误的。

只要我在响应中设置了Last-Modified标头,浏览器发出的第一个响应就是:

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

第二次回应有预期:

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

如果我避免发送If-Modified-Since标头,则每个请求都会返回must-revalidate, no-cache, private

请求是否已在proddev环境中生效无关紧要。

2 个答案:

答案 0 :(得分:8)

我遇到了同样的问题。我不得不提供'公共'标题我的cdn。默认情况下,在prod模式下启用网关缓存时,它会返回200 OK,私有,nocache必须验证标头。

我以这种方式解决了问题。

在app.php中,在我向用户发送响应($ respond-> send)之前,我已将缓存控制标头覆盖为空白,并将缓存标头设置为public和max age(某个值)。

来自app.php的

//代码段

    $response = $kernel->handle($request);
    $response->headers->set('Cache-Control', '');
    $response->setPublic();
    $response->setMaxAge(86400);
    $response->send();        

答案 1 :(得分:-4)

您的体验是有意的。 Symfony2 Docs明确说明使用私有公开时的情况,默认为私有