Symfony 3.4 http缓存,总是Cache-Control:max-age = 0,必须重新验证,私有

时间:2018-06-14 15:33:24

标签: symfony caching foshttpcachebundle

我尝试注释

 * @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缓存并允许发送缓存私有 - 但没有任何改变。

3 个答案:

答案 0 :(得分:4)

此行为从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

答案 1 :(得分:0)

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

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

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

答案 2 :(得分:0)

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

就我而言,我只需要特定控制器的共享缓存头即可。

Symfony 3.4的Workaroung。*:

Symfony\Component\HttpKernel\EventListener\SessionListener中创建一个优先级低于services.yml的侦听器(不知道是否建议这样做):

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

}