在我的项目中,我使用esi和Varnish作为缓存代理服务器。主块有1小时的ttl,内部有10分钟的几个街区。是否有可能将esi标签包括在主esi标签中,如下所述?
main.html.twig
<esi:include src="/?action=menu/topBar"/>
<esi:remove>
{% include('partials/header/topBar.html.twig') %}
</esi:remove>topBar.html.twig
<esi:include src="/?action=index/extraLink" />
<esi:remove>
{% include('partials/header/extraLink.html.twig') %}
</esi:remove>发布于 2020-05-13 11:28:29
当然可以递归地处理ESI。这只是一个如何配置您的VCL的问题。
我看你在用Twig渲染ESI标签。我将假设您使用Symfony框架来处理那些Twig模板。如果是这样的话,解决方案非常简单。
ESI,Twig & Symfony
请先看看https://symfony.com/doc/current/http_cache/esi.html。
Symfony为Twig提供了一个render函数,它将控制器路由作为内部子请求处理,并直接返回HTML。这是你的{% include %}电话的另一种选择。
但最酷的是,Symfony也有一个用于Twig的render_esi函数。这将采用控制器路由,并将其自动输出为带有必要src属性的ESI标记。
Symfony验证它是否位于支持ESI的Varnish服务器后面。它是用握手的方法来完成的。如果结果证明ESI验证没有成功,它将回到典型的render行为,只返回HTML作为内部子请求。
这种行为与使用
<exi:include />和<esi:remove />作为后盾的Twig脚本相同。render_esi函数以更有效的方式处理这一问题。
如果您的Symfony安装不支持render_esi函数,请安装以下Composer包:https://packagist.org/packages/symfony/twig-bridge
ESI验证握手
为了确保Symfony能够进行正确的验证,在幕后进行以下操作:
support
Surrogate-Capability标头,以宣布它提供ESI Surrogate-Control标头,以指示Surrogate-Capability标头也能处理ESI。
以下是这些标题的一个示例:
Surrogate-Capability: abc=ESI/1.0
Surrogate-Control: content="ESI/1.0"你需要的VCL来实现这一点
正如在https://symfony.com/doc/current/http_cache/varnish.html上所描述的,您可以使用以下VCL片段来处理VCL:
sub vcl_recv {
// Add a Surrogate-Capability header to announce ESI support.
set req.http.Surrogate-Capability = "abc=ESI/1.0";
}
sub vcl_backend_response {
// Check for ESI acknowledgement and remove Surrogate-Control header
if (beresp.http.Surrogate-Control ~ "ESI/1.0") {
unset beresp.http.Surrogate-Control;
set beresp.do_esi = true;
}
}递归ESI
您需要的Twig语法如下:
main.html.twig:
{% render_esi("/?action=menu/topBar") %}topBar.html.twig:
{% render_esi("/?action=index/extraLink") %}有关https://symfony.com/doc/current/reference/twig_reference.html#render-esi的更多信息,请参见render_esi。
https://stackoverflow.com/questions/61772834
复制相似问题