2013-07-18 73 views
4

爲了設置,而不在控制器中的高速緩存可以做到這一點的響應:無緩存標頭註釋

$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"]... 

給了我一個語法錯誤,不期望「[」,所以我試着如上。

+1

Normaly包含HashMap用大括號定義在註釋中。試試看:'@Cache(vary = {「...」})' –

+0

我試過了, 和使用:'''vary =「no-cache,must-revalidate,no-store」'' 在響應頭中,我總是發現'''改變了no-cache,must-revalidate,no-store''',但是繼續採用緩存 – Lughino

+0

媽媽,你會在響應中獲得頭文件? –

回答

9

你在混合兩件事。在您的第一個片段中,您將設置緩存控制標題,但是您需要使用註釋設置Vary標題。但是VaryCache-Control標題完全不同,其中no-cache, must-revalidate, no-store應該是。 Vary意味着在其上認爲請求(即Cookies)響應可以變化。看到這個答案的理解:https://stackoverflow.com/a/1975677/2084176

在你的情況(無緩存),你可以依靠on the defaults,其中的symfony套,如果沒有高速緩存頭存在:

Symfony2中自動設置一個合理的和保守的cache控制當沒有由開發者設置通過以下規則頭:如果沒有高速緩存標頭被定義(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 } 
+0

感謝您的支持澄清,但如果我沒有設置任何東西,當我按下後退按鈕瀏覽器讓我與緩存,但如果我設置'''$ response-> headers-> addCacheControlDirective('no-cache',true); $ response-> headers-> addCacheControlDirective('max-age',0); $ response-> headers-> addCacheControlDirective('must-revalidate',true); $ response-> headers-> addCacheControlDirective('no-store',true);''' 瀏覽器不會保留緩存,每次按下後退按鈕都會重新載入頁面。 – Lughino

+0

您不得設置任何緩存頭文件來採取此默認操作。沒有Vary標題,什麼都沒有。但後退按鈕是瀏覽器特定的行爲,您無法對其進行下注。 '無店'應該在大多數情況下工作,但嗯。這裏是另一個很好的答案:http://stackoverflow.com/a/866866/2084176 –

+0

我已經嘗試在Chrome和Firefox上,我都有相同的結果。 如果我按照你所說的設置'''no-store'''不再需要緩存。 現在的問題是:是否可以在註釋中設置'''no-store'''或者至少在控制器中設置一次? – Lughino

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