Symfony 3.4 http 缓存,总是 Cache-Control: max-age=0, must-revalidate, private
Symfony 3.4 http cache , always Cache-Control: max-age=0, must-revalidate, private
我在注释中尝试
* @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 那样的反向代理吗?
https://symfony.com/doc/3.4/http_cache.html#symfony-reverse-proxy
此外,在您的示例中,注释具有 public=false,而控制器具有 publictrue。
另一个可能的问题是您的网络服务器(Apatche 等)被配置为添加 header 或者您的 .htaccess 文件中的选项指定了这一点。
此行为是 Symfony 3.4 和 4.0 的新行为。如果用户 session 已初始化,它将始终按照您的问题所述设置 headers。
在 Symfony 4.1 中引入,您可以覆盖此行为。然而,由于这是一项新功能,因此不会向后移植到 Symfony 3.4。
$response->headers->set(AbstractSessionListener::NO_AUTO_CACHE_CONTROL_HEADER, 'true');
您可以在 Symfony 文档中阅读相关内容:HTTP Caching and User Sessions
可能最好的方法是使用 Service decoration,但我现在更喜欢肮脏的方法。
在我的例子中,我只需要特定控制器的共享缓存 headers。
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);
}
}
我在注释中尝试
* @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 那样的反向代理吗? https://symfony.com/doc/3.4/http_cache.html#symfony-reverse-proxy
此外,在您的示例中,注释具有 public=false,而控制器具有 publictrue。
另一个可能的问题是您的网络服务器(Apatche 等)被配置为添加 header 或者您的 .htaccess 文件中的选项指定了这一点。
此行为是 Symfony 3.4 和 4.0 的新行为。如果用户 session 已初始化,它将始终按照您的问题所述设置 headers。
在 Symfony 4.1 中引入,您可以覆盖此行为。然而,由于这是一项新功能,因此不会向后移植到 Symfony 3.4。
$response->headers->set(AbstractSessionListener::NO_AUTO_CACHE_CONTROL_HEADER, 'true');
您可以在 Symfony 文档中阅读相关内容:HTTP Caching and User Sessions
可能最好的方法是使用 Service decoration,但我现在更喜欢肮脏的方法。
在我的例子中,我只需要特定控制器的共享缓存 headers。
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);
}
}