-->

随着Symfony2中为什么内部缓存的响应ESI标签忽略?(With Symfony2 why ar

2019-08-17 06:17发布

我有一个电子商务应用程序,我尝试设置缓存 - 最初通过的Symfony2反向代理,但后来最终通过光油生产。 我使用的Apache2的Symfony 2.1.8。

我的问题是我不能让ESI标签进行重新检查每一个请求时,主控制器动作被缓存(像购物篮内容的私人内容很重要),但我不明白为什么。

例如,我缓存用下面的代码的网页:

public function indexAction(Request $request)
{
    // check cache
    $homepage = $this->getHomepage();

    $response = new Response();
    $response->setPublic();
    $etag = md5('homepage'.$homepage->getUpdated()->getTimestamp());
    $response->setETag($etag);
    $response->setLastModified($homepage->getUpdated());

    if ($response->isNotModified($request))
    {
        // use cached version
        return $response;
    }
    else
    {
        return $this->render(
            'StoreBundle:Store:index.html.twig',
            array(
                'page' => $homepage
            ),
            $response
        );
    }
}

所呈现的模板延伸,它包括以下ESI以显示篮基座布局模板:

{% render 'PurchaseBundle:Basket:summary' with {}, { 'standalone': true } %}

(编辑:阅读迭戈的回答后,我还使用了推荐的语法:

{% render url('basket_summary') with {}, {'standalone': true} %}

不幸的是这并没有什么不同。)

我一直在玩的篮子总结了不少的代码,但是这是我目前。

public function summaryAction()
{
    $response = new Response();
    $response->setPrivate();
    $response->setVary(array('Accept-Encoding', 'Cookie'));

    if ($this->basket->getId())
    {
        $etag = md5($this->getUniqueEtag());
        $response->setLastModified($this->basket->getUpdated());
    }
    else
    {
        $etag = md5('basket_summary_empty');
    }

    $response->setETag($etag);

    if ($response->isNotModified($this->request))
    {
        // use cached version
        return $response;
    }
    else
    {
        return $this->render(
            'PurchaseBundle:Basket:summary.html.twig',
            array(
                'basket' => $this->basket
            ),
            $response
        );
    }
}

在除首页(尚未缓存)篮下总结缓存的工作就好了其他页面,它总是显示正确的数据。 当您返回到你会看到过时的信息的网页这只是。 记录证实, summaryAction不叫在网页上,除非indexAction实际上呈现。

编辑

使用error_log($kernel->getLog())每个页面请求我得到这个对于非缓存页之后:

GET /categories/collections: miss; GET /_internal/secure/PurchaseBundle:Basket:summary/none.html: stale, valid, store; GET /_internal/secure/CatalogBundle:Search:form/none.html: miss; GET /esi/menu/main: fresh

而这对于缓存的网页:

GET /: fresh

我必须失去了一些东西很明显,但文档似乎没有覆盖这一点,但它暗示这只是事情ESI是应该用于排序。

Answer 1:

看来,ESI在Symfony2中与您所使用的Latmodified / Etag的缓存验证结构不工作。 在这里看到: https://groups.google.com/forum/?fromgroups=#!topic/symfony2/V4BItzpLbOs

类似的问题在这里: 边缘端包含在Symfony的2验证缓存

我一直试图做同样的你,却只能得到ESI通过使用过期的缓存工作。



Answer 2:

由于2.0.20 / 2.1.5 Symfony2中需要一个完全合格的URL,而不是控制器逻辑路径,按照CVE-2012-6431 。 所以,而非目前ESI的:

{% render 'PurchaseBundle:Basket:summary' with {}, { 'standalone': true } %}

您应该创建一个路由,然后使用URL方法上的树枝:

{% render url('basket_summary') with {}, {'standalone': true} %}

还要注意的是今日(3月1日)的Symfony的一个新的稳定版本(2.2.0)已经发布了关于子请求管理重大改进 。 有了这个新的版本,你可以采取两种方法(从提取的主版本书中的HTTP缓存章):

{# you can use a controller reference #}
{{ render_esi(controller('...:news', { 'max': 5 })) }}

{# ... or a URL #}
{{ render_esi(url('latest_news', { 'max': 5 })) }}

在联动章节的当前版本的旁注是值得一读为好,因为它们包含的信息和建议很好,可以帮助您找到实际问题美味件。



文章来源: With Symfony2 why are ESI tags inside cached responses ignored?