我正在尝试使用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 header(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
更新
由于我无法访问原始代码,因此尝试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
。
请求是否已在prod
或dev
环境中生效无关紧要。
答案 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明确说明使用私有和公开时的情况,默认为私有。