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

标签 caching symfony cache-control http-caching

我正在尝试使用 http 缓存。在我的 Controller 中,我设置响应如下:

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

开发模式

在开发环境中,第一个响应是带有以下 header 的 200:

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

在接下来的 2 分钟内,每个响应都是带有以下 header 的 304:

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

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

产品模式

在生产模式下响应 header 是不同的。请注意,在 app.php 中,我将内核包装在 AppCache 中。

第一个响应是带有以下 header 的 200:

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

所以这是一个私有(private)的无缓存响应。

下一个请求几乎都是我所期望的;带有以下 header 的 304:

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

我应该担心吗?这是预期的行为吗?

如果我把 Varnish 或 Akamai 服务器放在它前面会发生什么?

我做了一些调试,我认为由于上次修改的 header ,响应是私有(private)的。 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 {
    // ... 
}

Response::isValidateable()如果 Last-Response 或 ETag header 存在,则返回 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 .

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

一旦我在响应上设置了 Last-Modified header ,浏览器发出的第一个响应就会显示:

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

第二个响应的预期:

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

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

请求是在 prod 还是 dev 环境中发出并不重要。

最佳答案

我也遇到过同样的问题。我必须为我的 CDN 提供“公共(public)” header 。默认情况下,当在生产模式下启用网关缓存时,它会返回 200 OK(私有(private)),nocache 必须验证 header 。

我就是这样解决问题的。

在app.php中,在向用户发送响应($respond->send)之前,我已将缓存控制 header 覆盖为空白并将缓存 header 设置为公共(public)和最大年龄(某个值)。

//app.php 中的代码片段

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

关于caching - 如果第一个响应是 AppCache (Symfony2) 私有(private)的,可以吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9568074/

相关文章:

hibernate - Hibernate 二级缓存对 "find by primary key"以外的任何东西有用吗?

php - 中止和恢复 Symfony 控制台命令

php - .htaccess:缓存控制,我如何处理网站更新?

asp.net-mvc - ASP.NET MVC 3 : what and when to cache and how to decide?

php apc_fetch 所有 id

mysql - hibernate JPA+mysql : can not disable caching in createNativeQuery

php - Assets / Twig : An exception has been thrown during the compilation of a template (Unable to find file)

forms - symfony2 通过服务来形成主题

node.js - 使用 ExpressJS 为每个文件设置缓存控制