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


140

我正在尝试使用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内核使用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 {
    // ... 
}

如果存在Last-Response或ETag标头,则Response :: isValidateable()返回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标准版本重现该方案

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

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环境了。


3
当我禁用$ kernel = new AppCache($ kernel); 它向我公开显示。但随后它将始终以代码200进行响应...我将其用作遐想代理nginx。
迈克尔

app.phpapp_dev.php一样吗?(忽略调试和环境)
Florian Klein

1
我无法再访问该项目,因此无法确认。我记得控制器是启用了AppCache的默认控制器。
Jakub Zalas 2013年

1
@Florian我尝试重现该问题,并且最新的Symfony版本(请参阅更新)的行为有所不同。
Jakub Zalas 2013年

2
您是否会debug=>true在AppCache中设置getOptions()以便获取X-Symfony-Cache标头?
denkiryokuhatsuden 2013年

Answers:


9

我也遇到过同样的问题。我必须在我的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();        

尽管它们在控制者中公开,但您是否收到私人回复?
雅各布·扎拉斯

是的,如果我启用网关缓存并以产品模式运行它。我需要上述解决方案来处理静态内容。
srikanthsatturi 2014年

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.