No cache header with annotation

10,938

You are mixing two things. In your first snippet you are setting cache control headers, but with the annotation you want to set the Vary header. But Vary is complete different than the Cache-Control header, in which no-cache, must-revalidate, no-store should stand. Vary means on which thinks of the request (i.e. Cookies) the Response can vary. See this answer for understanding: https://stackoverflow.com/a/1975677/2084176

In your case (no-cache) you can rely on the defaults, which symfony sets, if no cache headers are present:

Symfony2 automatically sets a sensible and conservative Cache-Control header when none is set by the developer by following these rules:

  • If no cache header is defined (Cache-Control, Expires, ETag or Last-Modified), Cache-Control is set to no-cache, meaning that the response will not be cached;

EDIT: if you need to set the cache header for every controller action, you can work with the kernel.response event. Create a listener which reacts on this event and modify the response with appropriate cache control.

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

and in your services.yml

services:
    kernel.listener.your_listener_name:
        class: Acme\DemoBundle\EventListener\AcmeCacheListener
        tags:
            - { name: kernel.event_listener, event: kernel.response, method: onKernelResponse }
Share:
10,938
Lughino
Author by

Lughino

Always passionate about of computing and solving logic problems. In recent years I have gained experience in leadership in medium sized team. From the development side, I discovered a love for the MEAN stack, where the coupled javascript server side and NoSQL technologies have been adopted in all my projects.

Updated on June 05, 2022

Comments

  • Lughino
    Lughino almost 2 years

    In order to set the response without the cache in the controller you can do this:

    $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;
    

    But using annotations, to ensure that each method has the same result, how can you do?

    I tried so but continues to save the cache and if I use the browser's Back button keeps the cache:

    /**
     * @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());
    }
    

    If imposed as the documentation says:

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

    gives me a syntax error which does not expect "[", so I tried as above.