代码之家  ›  专栏  ›  技术社区  ›  delboy1978uk

渲染一个不带缓存的细枝模板

  •  -1
  • delboy1978uk  · 技术社区  · 6 年前

    我们的Symfony项目有一个登录小部件,我被告知应该通过AJAX加载它,以免弄乱页面缓存。

    它显示“登录”或用户的电子邮件地址(如果用户已经登录)。

    问题是,这个细枝模板也被缓存了!所以通过ajax加载它并没有帮助。

    如何让Twig每次都从头开始呈现模板,而不禁用整个缓存站点?

    模板本身非常简单:

        <small id="login-username">
            {% if is_granted('ROLE_USER') %}
                {{ app.user.username }}
            {% else %}
                {{ 'LoginWidgetElement.login' | trans }}
            {% endif %}
        </small>
    

    元素的类也非常简单:

    <?php
    
    namespace Xyz\Sports\Element\LoginWidget;
    
    use Xyz\Library\AbstractElement;
    use Sensio\Bundle\FrameworkExtraBundle\Configuration as Config;
    
    /**
    * @Config\Template("@LoginWidgetElement/login_widget.html.twig")
    */
    class LoginWidgetElement extends AbstractElement
    {
        public function render()
        {
            return [];
        }
    
        public function renderPreview()
        {
            return $this->render();
        }
    }
    

    更新

    twig模板似乎正在检查,因此我尝试发送一个响应,告诉浏览器不要缓存,但仍然需要大约15个请求才能更改变量!!??

    细枝缓存:

    <small id=\"login-username\">
                ";
            // line 9
            if ($this->extensions['Symfony\Bridge\Twig\Extension\SecurityExtension']->isGranted("ROLE_USER")) {
                // line 10
                echo "                ";
                echo twig_escape_filter($this->env, twig_get_attribute($this->env, $this->source, twig_get_attribute($this->env, $this->source, (isset($context["app"]) || array_key_exists("app", $context) ? $context["app"] : (function () { throw new Twig_Error_Runtime('Variable "app" does not exist.', 10, $this->source); })()), "user", array()), "username", array()), "html", null, true);
                echo "
                ";
            } else {
                // line 12
                echo "                ";
                echo twig_escape_filter($this->env, $this->extensions['Symfony\Bridge\Twig\Extension\TranslationExtension']->trans("LoginWidgetElement.login"), "html", null, true);
                echo "
                ";
            }
            // line 14
            echo "        </small>
    

    所以有一个 isGranted('ROLE_USER') 检查。现在,在我的渲染方法中:

    $response = new Response();
    $response->headers->set('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0, post-check=0, pre-check=0');
    $response->headers->set('Pragma', 'no-cache');
    
    $body = $this->twig->render('@LoginWidgetElement/login_widget.html.twig');
    $response->setContent($body);
    
    return $response;
    

    但还是没有雪茄:'-(

    1 回复  |  直到 6 年前
        1
  •  1
  •   delboy1978uk    6 年前

    看起来设置缓存头有自己的方法,我们不应该只使用 $response->headers->set($key, $val);

    我将逻辑转化为一个可重用的特征:

    <?php
    
    namespace Xyz\Library\Traits;
    
    use Symfony\Component\HttpFoundation\Response;
    
    trait NoCacheHeadersTrait
    {
        public function disableBrowserCache(Response $response) : Response
        {
            $response->headers->addCacheControlDirective('no-store', true);
            $response->headers->addCacheControlDirective('no-cache', true);
            $response->headers->addCacheControlDirective('must-revalidate', true);
            $response->headers->addCacheControlDirective('max-age', 0);
            $response->headers->addCacheControlDirective('post-check', 0);
            $response->headers->addCacheControlDirective('pre-check', 0);
            $response->headers->set('Pragma', 'no-cache');
    
            return $response;
        }
    }
    

    现在我 use 类中的trait,以及我的render方法中的trait现在如下所示:

    public function render()
    {
        $response = $this->disableBrowserCache(new Response());
        $body = $this->twig->render('@LoginWidgetElement/login_widget.html.twig');
        $response->setContent($body);
    
        return $response;
    }