没有带注释的缓存头

时间:2013-07-18 19:38:50

标签: symfony symfony-2.3

要在控制器中设置没有缓存的响应,您可以执行以下操作:

$response = new Response();
$result = $this->renderView(
        'AcmeDemoBundle:Default:index.html.twig',
         array('products' => $products, 'form' => $form->createView()));
$response->headers->addCacheControlDirective('no-cache', true);
$response->headers->addCacheControlDirective('max-age', 0);
$response->headers->addCacheControlDirective('must-revalidate', true);
$response->headers->addCacheControlDirective('no-store', true);
$response->setContent($result);

return $response;

但是使用注释,为了确保每个方法都有相同的结果,你怎么办?

我试过但是继续保存缓存,如果我使用浏览器的后退按钮保留缓存:

/**
 * @Cache(maxage="0", vary="no-cache, must-revalidate, no-store", smaxage="0", expires="now", public="false")
 */
class DefaultController extends Controller
{
/**
 * Homepage: show products
 * 
 * @Route("/", name="homepage")
 * @Template
 */
public function indexAction()
{
    $sessionCart = $this->get('demo');
    $filters = $sessionCart->getFilters($this->getDoctrine()->getEntityManager());
    $products = $this->getDoctrine()->getRepository('AcmeDemoBundle:Product')->search($filters);
    $form = $this->createForm(new FilterType, $filters);

    return array('products' => $products, 'form' => $form->createView());
}

如果文件说明:

@Cache(vary=["no-cache", "must-revalidate", "no-store"]...

给了我一个语法错误,不会指望“[”,所以我尝试了如上。

2 个答案:

答案 0 :(得分:13)

你混合了两件事。在您的第一个代码段中,您要设置缓存控制标头,但是要使用注释设置Vary标头。但Vary完全不同于Cache-Control标题,其中no-cache, must-revalidate, no-store应该成立。 Vary表示响应可以变化的请求(即Cookie)。请参阅此答案以了解:https://stackoverflow.com/a/1975677/2084176

在您的情况下(无缓存),如果没有缓存标头,您可以依赖on the defaults,symfony设置:

  

当开发人员没有按照以下规则设置时,Symfony2会自动设置合理且保守的Cache-Control标头:

     
      
  • 如果未定义缓存标头(Cache-ControlExpiresETagLast-Modified),则Cache-Control设置为no-cache,意思是响应不会被缓存;
  •   

编辑:如果您需要为每个控制器操作设置缓存标头,则可以使用kernel.response事件。创建一个响应此事件的侦听器,并使用适当的缓存控制修改响应。

namespace Acme\DemoBundle\EventListener;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;

class AcmeCacheListener
{
    public function onKernelResponse(FilterResponseEvent $event)
    {
        $response = $event->getResponse();

        $response->headers->addCacheControlDirective('no-cache', true);
        $response->headers->addCacheControlDirective('max-age', 0);
        $response->headers->addCacheControlDirective('must-revalidate', true);
        $response->headers->addCacheControlDirective('no-store', true);
    }
}

并在services.yml

services:
    kernel.listener.your_listener_name:
        class: Acme\DemoBundle\EventListener\AcmeCacheListener
        tags:
            - { name: kernel.event_listener, event: kernel.response, method: onKernelResponse }

答案 1 :(得分:0)

我想主要的问题是Cache注释没有no-cache,no-store和must-revalidate的选项。我无法解释原因。 作为Patrick的答案的补充,如果你有多个控制器,并且你想将标题只应用于一个,你可以检查监听器内的控制器类,如:

class AcmeCacheListener
{
    public function onKernelResponse(FilterResponseEvent $event)
    {
        $controller = $event->getRequest()->attributes->get('_controller');
        $requiredController = "Acme\Controller\DefaultController";
        if( substr($controller, 0,strlen($requiredController)) == $requiredController) {

            $response = $event->getResponse();
            $response->headers->addCacheControlDirective('no-cache', true);
            $response->headers->addCacheControlDirective('max-age', 0);
            $response->headers->addCacheControlDirective('must-revalidate', true);
            $response->headers->addCacheControlDirective('no-store', true);
         }
    }
}