3

I can't use a normal RedirectResponse - Drupal prevent's it when it detects I'm redirecting to an external site. Instead I need to use a TrustedRedirectResponse, but this is a cacheable response - which I don't want.

  • I think you can retrieve the cacheable metadata object from the response object, and then set the cache max-age to 0. Or add cache contexts or tags. – mradcliffe Jan 11 '17 at 13:06
5

Disable caching in responses

You can build the cacheable metadata and put max-age = 0 in it:

$build = [
  '#cache' => [
    'max-age' => 0,
  ],
];
$cache_metadata = \Drupal\Core\Cache\CacheableMetadata::createFromRenderArray($build);
$response->addCacheableDependency($cache_metadata);

If you want to put this in one line:

$response
 ->addCacheableDependency((new \Drupal\Core\Cache\CacheableMetadata())->setCacheMaxAge(0));

Disable caching for anonymous requests

Also you have to disable the page cache for anonymous requests

\Drupal::service('page_cache_kill_switch')->trigger();

This is necessary no matter if you use a normal redirect response or one with drupal caching.

| improve this answer | |
  • Thanks, that worked. Can you elaborate a bit on why it's necessary to invoke the kill switch? If I set a max age of 0 on the response, wouldn't that tell external page caches and Drupal's internal page cache to NOT cache the page? – Brian Jan 17 '17 at 15:50
  • 1
    For a redirect response it should be. But caching this is not the main purpose of the internal page cache. It is designed for a page with many elements and it was decided to not bubble up the cache max age, because then one block could prevent the internal page cache from doing its job. And by default drupal 8 should be as fast as possible for anonymous traffic (which it is). See this issue drupal.org/node/2352009 – 4k4 Jan 17 '17 at 16:13
  • Above solution didn't work. Still getting logic exception - LogicException: The controller result claims to be providing relevant cache metadata, but leaked metadata was detected. Please ensure you are not rendering content too early. Returned object class: Drupal\Core\Routing\TrustedRedirectResponse. in Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext() (line 154 of /vagrant/digi-drupal/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php). – Renuka Kulkarni Mar 24 at 12:29
  • @RenukaKulkarni, this error is not caused by the code in the answer. It must be other code you have added for rendering content. BTW, rendering can also be converting a URL to a string or executing an entity query with access checks enabled, see drupal.stackexchange.com/a/225963/47547 – 4k4 Mar 24 at 12:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.