How to do a non-cached 301 redirect?

16,714

Solution 1

301 is a permanent redirect, so caching makes sense. If your redirect isn't permanent, use 307 (temporary redirect), 302 (found) or 303 (see other).

See here for the appropriate use cases.

To elaborate on the differences between these three:

  • 307 is the generic, temporary redirect for when a resource is moved. For example, a URL like domain.com/news/latest might do a 307 redirect to the latest news article, domain.com/news/article-594873. Since this temporary redirection may persist for a while (that particular article may be the latest for several hours), browsers might cache the redirect. To control the degree to which they do, use cache control headers.
  • 303 is the redirect that must not be cached, ever. For example, POSTing a new article to domain.com/news might create a new news article, and a 303 redirect to it is provided to domain.com/news/article-978523. Since another POST request results in a completely different, new article being created, it cannot be cached.
  • 302 is a bit stranger, I've never used it myself. Apparently it's more of a legacy substitute for the 303, for earlier HTTP 1.0 version clients who do not understand the 303.

Since you asked specifically about PHP:

<?php
function header_redirect_permanent($url)
    {
    header($_SERVER['SERVER_PROTOCOL'] . ' 301 Moved Permanently', true, 301);
    header('Location: ' . $url);
    }

function header_no_cache()
    {
    header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
    header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); // past date to encourage expiring immediately
    }

You can stop agents from caching a 301 as well, if you must, using the above cache control headers like this:

header_no_cache();
header_redirect_permanent($url);

or simply add

header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
header('Location:'.$url, true, 301);
exit;

Solution 2

A http status code 301 without caching can be used to do URL canonicalization while retaining the tracking functionality.

To prevent a 301 redirect from being cached just set the cache control headers, then you can undo the redirect and clients (bot and browsers) will no longer get redirected.

header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
header('Location:'.$url, true, 301);
exit;

This is useful when you want browsers to update the URL in bookmarks and bots to update their index but still be able to track them or undo the redirect by redirecting back to the original URL without causing infinite loops or other nonsense.

This does not in any way mean that the 301 code has to be used for all redirects, on the contrary, different kinds of redirect have different status codes which Core Xii summarized.

Share:
16,714
Timo Huovinen
Author by

Timo Huovinen

"The formulation of a problem is often more essential than its solution, which may be merely a matter of mathematical or experimental skill." -Albert Einstein Web Dev that enjoys HTML/CSS, but mainly works with JavaScript, Golang, PHP and SQL. Considers himself to be a beginner forever, even though has experience in the field, the fact that he is self-taught shows with constant beginner questions. Talks about himself in third person. Lacks common sense.

Updated on June 17, 2022

Comments

  • Timo Huovinen
    Timo Huovinen almost 2 years

    A while ago all browsers changed their behaviour and started caching 301 redirects, I would like to know how to do a 301 redirect that is not cached in php?

    • cspolton
      cspolton over 11 years
      Why shouldn't browsers cache 301 redirects, if they are by definition permanent? ... I know, the business can change they minds!
    • Petah
      Petah over 11 years
      Core Xii's answer is correct. However to add to that you can use the Firefox/Chrome Developer Tools plugin to clear redirect and DNS caches.
    • Timo Huovinen
      Timo Huovinen over 11 years
      Quote: Interpreting “permanent” as “eternal” amongst man, in a temporary world, job, company, mindset, etc, is plain ignorant. here
    • Timo Huovinen
      Timo Huovinen over 11 years
    • inf3rno
      inf3rno over 10 years
      Use 307 instead, that's for temporarily redirection...
    • Timo Huovinen
      Timo Huovinen over 10 years
      @cspolton it seems that the definition of "permanent" varies a lot, so lets just look at the implementation behind the scenes and work with that.
  • Timo Huovinen
    Timo Huovinen over 11 years
    But is it possible to prevent a 301 from being cached, or control its cache time, maybe using cache headers?
  • Core Xii
    Core Xii over 11 years
    You can try. May I ask why you're trying to prevent the caching of a 301 redirect? I can't think of any good reason.
  • Timo Huovinen
    Timo Huovinen over 11 years
    For search engines to carry more link juice, but to still be able to change the redirect.
  • Core Xii
    Core Xii over 11 years
    If you wish to retain the ability to change the redirect, then it isn't permanent, now is it? The very standards our web is built around state that a 301 is permanent. Do not attempt to break the web by misusing the protocols for some shady "SEO" practices.
  • Timo Huovinen
    Timo Huovinen over 11 years
    The purposes are not shady and I have the right to misuse the protocols if I consider it the right thing to do so, can a 301 redirect's cache be controlled in theory? yes or no?
  • Core Xii
    Core Xii over 11 years
    As the reference states, "This response is cacheable unless indicated otherwise.". I've added an example on how to indicate otherwise, using the Cache-Control and Expires headers. I still advise against it, but do as you see fit.
  • Timo Huovinen
    Timo Huovinen over 11 years
    would you be so kind to make a full example of a 301 redirect that is not cached so that I can accept your answer?
  • Core Xii
    Core Xii over 11 years
    As per my example code, sending the 301, Location, Cache-Control and Expires headers accomplishes that.
  • wizonesolutions
    wizonesolutions almost 10 years
    @TimoHuovinen: I've tested the solution of setting headers, and it works great. I recommend accepting the answer so core-xii can get credit.
  • Arkaine55
    Arkaine55 over 9 years
    Since Core Xii gave all the same information in his answer (before you "answered it yourself") it would have been nice of you to give him the credit and either comment or edit his answer. As an aside, (good) robots that you may be SEO-ing for understand cache-control too. So using a 301 like an uncachable 302/307 will at most give you the benefit of an uncached 302/307 and at worst a penalty for doing something that could be considered under-handed.
  • Joe Hakooz
    Joe Hakooz over 7 years
    Since some can't comprehend why to "misuse" 301 redirects, here's an example... We do it so we can control tracking file download events in Google Analytics. And iTunes (for example) accept 301 redirects when pointing to MP3 files as podcasts, while other codes did not seem to work at the time of development.