How to do a non-cached 301 redirect?
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 todomain.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.
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, 2022Comments
-
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 over 11 yearsWhy shouldn't browsers cache 301 redirects, if they are by definition permanent? ... I know, the business can change they minds!
-
Petah over 11 yearsCore 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 over 11 yearsQuote: Interpreting “permanent” as “eternal” amongst man, in a temporary world, job, company, mindset, etc, is plain ignorant. here
-
Timo Huovinen over 11 yearsduplicate stackoverflow.com/questions/9020162/…
-
inf3rno over 10 yearsUse 307 instead, that's for temporarily redirection...
-
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 over 11 yearsBut is it possible to prevent a 301 from being cached, or control its cache time, maybe using cache headers?
-
Core Xii over 11 yearsYou 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 over 11 yearsFor search engines to carry more link juice, but to still be able to change the redirect.
-
Core Xii over 11 yearsIf 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 over 11 yearsThe 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 over 11 yearsAs the reference states, "This response is cacheable unless indicated otherwise.". I've added an example on how to indicate otherwise, using the
Cache-Control
andExpires
headers. I still advise against it, but do as you see fit. -
Timo Huovinen over 11 yearswould 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 over 11 yearsAs per my example code, sending the 301,
Location
,Cache-Control
andExpires
headers accomplishes that. -
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 over 9 yearsSince 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 over 7 yearsSince 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.