6

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.

4

2 回答 2

14

你混合了两件事。在您的第一个片段中,您正在设置缓存控制标头,但要使用要设置Vary标头的注释。但与标题Vary完全不同,应该站在其中。意味着响应可以改变的请求(即Cookies)。请参阅此答案以了解:https ://stackoverflow.com/a/1975677/2084176Cache-Controlno-cache, must-revalidate, no-storeVary

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

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

  • 如果没有定义缓存头(Cache-Control、或),Expires则设置为,表示响应不会被缓存;ETagLast-ModifiedCache-Controlno-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 }
于 2013-07-18T21:06:46.257 回答
0

我想主要问题是缓存注释没有无缓存、无存储和必须重新验证的选项。我无法解释为什么。作为对帕特里克的回答的补充,如果您有多个控制器并且您只想将标头应用于一个,您可以检查侦听器中的控制器类,如下所示:

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);
         }
    }
}
于 2016-08-30T16:20:56.447 回答