13

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?

Timo Huovinen
  • 53,325
  • 33
  • 152
  • 143
  • 5
    Why shouldn't browsers cache 301 redirects, if they are by definition permanent? ... I know, the business can change they minds! – cspolton Aug 30 '12 at 08:17
  • 1
    Quote: Interpreting “permanent” as “eternal” amongst man, in a temporary world, job, company, mindset, etc, is plain ignorant. [here](http://getluky.net/2010/12/14/301-redirects-cannot-be-undon/) – Timo Huovinen Aug 30 '12 at 09:13
  • duplicate http://stackoverflow.com/questions/9020162/avoiding-301-redirect-caching – Timo Huovinen Aug 31 '12 at 07:25
  • 1
    Use 307 instead, that's for temporarily redirection... – inf3rno Dec 07 '13 at 08:51
  • @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 Dec 16 '13 at 17:42
  • 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. – Petah Aug 30 '12 at 08:20

2 Answers2

36

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;
Timo Huovinen
  • 53,325
  • 33
  • 152
  • 143
Core Xii
  • 6,270
  • 4
  • 31
  • 42
  • 1
    But is it possible to prevent a 301 from being cached, or control its cache time, maybe using cache headers? – Timo Huovinen Aug 30 '12 at 09:13
  • 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. – Core Xii Aug 30 '12 at 12:15
  • 3
    For [search engines](http://www.seomoz.org/learn-seo/redirection) to carry more link juice, but to still be able to change the redirect. – Timo Huovinen Aug 30 '12 at 13:24
  • 1
    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. – Core Xii Aug 30 '12 at 18:25
  • 1
    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? – Timo Huovinen Aug 31 '12 at 06:55
  • 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. – Core Xii Sep 01 '12 at 08:53
  • 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? – Timo Huovinen Sep 05 '12 at 19:13
  • As per my example code, sending the 301, `Location`, `Cache-Control` and `Expires` headers accomplishes that. – Core Xii Sep 05 '12 at 20:58
  • 1
    @TimoHuovinen: I've tested the solution of setting headers, and it works great. I recommend accepting the answer so core-xii can get credit. – wizonesolutions Aug 14 '14 at 22:31
  • 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. – Joe Hakooz Nov 02 '16 at 18:04
5

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.

Community
  • 1
  • 1
Timo Huovinen
  • 53,325
  • 33
  • 152
  • 143
  • 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. – Arkaine55 Aug 19 '14 at 20:27