【问题标题】:Symfony 3.4 http cache , always Cache-Control: max-age=0, must-revalidate, privateSymfony 3.4 http 缓存,总是 Cache-Control: max-age=0, must-revalidate, private
【发布时间】:2018-11-24 10:45:09
【问题描述】:

我在注释中尝试

 * @Cache(expires="+10 hours", public=false) 

或在控制器中

$maxAge = 60*60;
$response->setExpires(Carbon::create()->addHour());
$response->setSharedMaxAge($maxAge);
$response->setPublic();
$response->setMaxAge($maxAge);

还有Cache-Control: max-age=0, must-revalidate, private

应用程序使用会话,用户正在登录 - 我想要 - 缓存私有,但没有任何工作 - 我总是得到这个。

我已添加FOS\HttpCacheBundle\FOSHttpCacheBundle()

(只是添加)希望它覆盖 symfony 缓存并允许发送缓存私有 - 但没有任何改变。

【问题讨论】:

    标签: symfony caching foshttpcachebundle


    【解决方案1】:

    这种行为是 Symfony 3.4 和 4.0 的新行为。如果用户会话已初始化,它将始终按照您的问题中所述设置标题。

    在 Symfony 4.1 中引入,您可以覆盖此行为。然而,由于这是一项新功能,因此不会向后移植到 Symfony 3.4。

    $response->headers->set(AbstractSessionListener::NO_AUTO_CACHE_CONTROL_HEADER, 'true');
    

    您可以在 Symfony 文档中阅读相关内容:HTTP Caching and User Sessions

    【讨论】:

    • 我是不是读错了,或者这意味着在 v3.4 中,只要您有一个活动的用户会话,就不可能将 ESI 与 HTTP 缓存一起使用?
    • 显然你没看错。对于基于 ESI 的设置来说,这是一个重要的 B/C 中断,当会话 cookie 存在时(不管实际登录状态如何),甚至不能缓存与用户无关的响应。错误报告:github.com/symfony/symfony/issues/29151
    【解决方案2】:

    可能最好的方法是使用Service decoration,但我现在更喜欢肮脏的方式。

    在我的情况下,我只需要特定控制器的共享缓存标头。

    Symfony 3.4.* 的工作环境:

    services.yml中创建一个优先级低于Symfony\Component\HttpKernel\EventListener\SessionListener的监听器(不知道是否推荐):

    AppBundle\Listener\ResponseListener:
        tags:
            - { name: kernel.event_listener, event: kernel.response, priority: -1001 }
    

    然后在AppBundle\Listener\ResponseListener:

    <?php
    
    namespace AppBundle\Listener;
    
    use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
    
    class ResponseListener
    {
        public function onKernelResponse(FilterResponseEvent $event)
        {
            $response = $event->getResponse();
    
            $controller = $event->getRequest()->attributes->get('_controller');
            $requiredAssetAction = "AppBundle\Controller\Website\AssetsController::assetAction";
    
            if ($controller == $requiredAssetAction) {
                $response->headers->addCacheControlDirective('max-age', 900);
                $response->headers->addCacheControlDirective('s-maxage', 900);
                $response->headers->addCacheControlDirective('must-revalidate', true);
                $response->headers->addCacheControlDirective('public', true);
                $response->headers->removeCacheControlDirective('private');
    
            }
    
            $event->setResponse($response);
        }
    
    }
    

    【讨论】:

      【解决方案3】:

      您是否在使用像 Symfony 这样的反向代理? https://symfony.com/doc/3.4/http_cache.html#symfony-reverse-proxy

      此外,在您的示例中,注释具有 public=false 而控制器将具有 public true。

      另一个可能的问题是您的网络服务器(Apatche 等)被配置为添加该标头或在您的 .htaccess 文件中指定一个选项。

      【讨论】:

        猜你喜欢
        • 2019-01-17
        • 2011-02-25
        • 2015-02-14
        • 1970-01-01
        • 2020-08-11
        • 2015-10-19
        • 2021-04-19
        • 2015-04-08
        • 2019-07-09
        相关资源
        最近更新 更多