gpt4 book ai didi

caching - 使用 Symfony2,为什么缓存响应中的 ESI 标签会被忽略?

转载 作者:行者123 更新时间:2023-12-02 16:26:07 27 4
gpt4 key购买 nike

我有一个电子商务应用程序,我尝试为其设置缓存 - 最初通过 Symfony2 反向代理,但最终通过生产中的 Varnish。我在 Apache2 上使用 Symfony 2.1.8。

我的问题是,当缓存主 Controller 操作时,我无法为每个请求重新检查 ESI 标记(对于购物篮内容等私有(private)内容很重要),但我不明白为什么。

例如,我使用以下代码缓存主页:

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
);
}
}

在主页以外的页面(尚未缓存)上,购物篮摘要缓存工作得很好,它始终显示正确的数据。只有当您返回主页时,您才会看到过时的信息。日志记录确认,除非 indexAction 实际呈现,否则不会在主页上调用 summaryAction

编辑

在每个页面请求后使用 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 应该用来做的事情。

最佳答案

自 2.0.20/2.1.5 起,Symfony2 采用完全限定的 URL,而不是 Controller 逻辑路径,如 CVE-2012-6431 所示。 。因此,代替您当前的 ESI:

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

您应该创建一个路由,然后在 twig 上使用 url 方法:

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

另请注意,今天(3 月 1 日)Symfony (2.2.0) 的新稳定版本已发布,编号为 major improvements on sub-requests management 。在这个新版本中,您可以采用两种方法(摘自本书中 HTTP 缓存章节的 master version):

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

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

链接章节当前版本的旁注也值得一读,因为它们包含有趣的信息和不错的提示,可以帮助您找到实际问题。

关于caching - 使用 Symfony2,为什么缓存响应中的 ESI 标签会被忽略?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15163121/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com