Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No cache header with annotation

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.

like image 711
Lughino Avatar asked Jul 18 '13 19:07

Lughino


1 Answers

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 }
like image 112
Emii Khaos Avatar answered Nov 03 '22 17:11

Emii Khaos