5

I have a url that would normally redirect to a specific page, however, some code is run prior to this. I am returning a RedirectResponse instance, and it appears to be being cached. How can I force this not to be cached?

  • Are you sure Drupal is doing the caching, because browsers will sometimes cache redirects. – mpdonadio Dec 2 '16 at 18:20
  • For me, it really was Drupal, as the RedirectResponse uses 302 which browsers shouldn't cache. – gogowitsch Feb 8 '17 at 14:28
15

A response built from the RedirectReponse class is not cached. So you should not need to set any cache meta data. The problem here is probably the page cache for anonymous requests, which caches all responses, even redirects and no matter if they are cachable or not.

You can disable this cache by using the kill switch before returning the response:

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

This will only disable the Internal Page Cache. To control caches outside of drupal, like proxies or browser caches, go to /admin/config/development/performance and set a "Page cache maximum age".

  • You can try that, but in redirect.module, we explicitly use cacheable redirect responses to have them cached. I think they aren't by default. As the comment from @mpdonadio says, this might actually be the browser doing the caching – Berdir Dec 2 '16 at 19:44
  • The class name in the question is the original Symfony redirect response without Drupal caching. For the browser cache see my edit. – 4k4 Dec 3 '16 at 11:18
  • Yes, sorry, I was unclear. I meant those responses should actually not get cached, because to have them cached in redirect, we need to use a cacheable response. – Berdir Dec 3 '16 at 13:17
  • 1
    @Berdir RedirectResponseSubscriber changes ordinary RedirectResponse objects to LocalRedirectResponse objects which are cacheable. – Smartsheet eng Nov 8 '18 at 23:48
1

As noted in the comments above, RedirectResponseSubscriber does alter redirects. Here's the relevant snippet:

if (!($response instanceof SecuredRedirectResponse)) {
    try {
      // SecuredRedirectResponse is an abstract class that requires a
      // concrete implementation. Default to LocalRedirectResponse, which
      // considers only redirects to within the same site as safe.
      $safe_response = LocalRedirectResponse::createFromRedirectResponse($response);
      $safe_response->setRequestContext($this->requestContext);
    }

So if you have a custom redirect that should not be cached, then create a custom class that extends SecuredRedirectResponse and implement the required isSafe() method. You may wish to leverage LocalAwareRedirectResponseTrait to use there to verify the url is local, along with any other check to verify that this is your redirect and not a mis-use. Your redirect will then skip the block above and not be converted to a cacheable redirect. Thanks to @smartsheet-eng for pointing me in the right direction.

0

You may want to cache your response with CacheableRedirectResponse

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.