When a web server wishes to redirect a user's browser, which status code (ie, "200 OK") should it place in the response header? From my reading it seems the answer could be any one of the 3XX codes, but each of those codes seems to have a different description. Does it even matter which is used so long as "Location" is in the response header?
4 Answers
It depends entirely on why you're doing the redirect. I'll assume you've read RFC 2616.
You don't want to use 301 except potentially for things like page-renames. I am not aware of any CMS that does this automatically.
Clients with link editing capabilities ought to automatically re-link references to the Request-URI to one or more of the new references returned by the server, where possible.
302 is perfectly fine for a temporary GET-after-GET and is, by default, uncacheable. It should not be used for a GET-after-POST, since it actually means POST-after-POST (after asking the user for confirmation):
Note: RFC 1945 and RFC 2068 specify that the client is not allowed to change the method on the redirected request. However, most existing user agent implementations treat 302 as if it were a 303 response, performing a GET on the Location field-value regardless of the original request method. The status codes 303 and 307 have been added for servers that wish to make unambiguously clear which kind of reaction is expected of the client.
303 is for GET-after-POST. Ancient browsers might not support it, so you might not want to use it for GET-after-GET:
Note: Many pre-HTTP/1.1 user agents do not understand the 303 status. When interoperability with such clients is a concern, the 302 status code may be used instead, since most user agents react to a 302 response as described here for 303.
307 is for POST-after-POST (after confirming with the user). It can be used for GET-after-GET, but in that case you might as well use 302/303:
If the 307 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued.
As for compatibility, I wouldn't be surprised if a significant percentage (1%?) of users are behind broken proxies that don't understand 303 or 307, even if they claim to support HTTP/1.1. Meh.
-
Thanks for that. But I'm still confused over why you said "302 is deprecated" earlier. – Mike Jul 02 '11 at 01:25
-
Rather, "just use 302" is wrong in response to a POST request, unless you're happy with the possibility of different browsers interpreting it differently. – tc. Jul 02 '11 at 01:28
-
So you complain that "302 is deprecated" on other answers, and then come back with an answer that basically recommends using 302 for the sake of compatibility? – aroth Jul 02 '11 at 01:29
-
If you're uncomfortable with 302, then use one of the two codes it has been replaced by (303 or 307). – Julian Reschke Jul 02 '11 at 10:55
According to the Mozilla docs:
Redirection responses (of the form 3xx) indicate that the resource that the client requested has moved and the server is not able to serve it directly. Most of these responses contain some location information telling where to find the requested resource; user-agents often then retrieve it without further user interaction. The most common responses of this type are
301 Moved Permanently
, indicating that the URI given is no longer valid and has been moved to another place, and302 Found
which indicates that the resource has been temporarily moved to another place.Note: For webmasters, it is recommended to set up a
301 Moved Permanently
redirection when moving pages to another URI, during a site reorganization for example. That allows users following links to still reach the resource and it also teaches search engines and other services the new location of the resource, so that they can transfer their metadata to it. It is also important to add adequate cache headers to the301 Moved Permanently
response so that this information is cached by the client and prevents it from making unnecessary requests to the original URI prior to fetching the resource itself.
More detailed information about status codes can be found from the W3C. For a visual representation of how different status codes affect SEO, see SEO Guide to HTTP Status Codes.
-
Nice link, but it didn't really clear up the difference between 301/302 for me – Mike Jul 02 '11 at 01:10
-
3
-
The problem I have with 301 is, what if the URI being forwarded to is dynamic? It would suggest that a user agent would think the URI could be the same on each subsequent visit and not bother doing a second request. It would cache the URI on the first visit and not bother looking again. – Mike Jul 02 '11 at 01:18
-
1@Mike - If the URI being forwarded **to** is dynamic, then you are safe. But if the URI that you forward **from** is dynamic then you are probably better off going with code 302/307 to ensure that the browser still directs subsequent requests to the dynamic URI. – aroth Jul 02 '11 at 01:24
Response code 302. Or at least, that's what Java's HttpServletResponse
sends when you call sendRedirect()
. And if that's how Java does it, there's probably a reason.
The only difference between 301 and 302 semantically is that 301 indicates a "permanent redirect" and 302 indicates a "temporary redirect". Whether this translates into any difference in practice is entirely up to the client implementing the protocol.
For instance, the browser could decide that since 301 is permanent it will just remember the redirect URL that it gets back and never actually send the request for the original URL anymore. But that would be entirely up to the browser implementation.
Perhaps a reasonable rule of thumb is that if you are moving static content to a new location, always use 301. But if you are sending the redirect in response to a request to some dynamic code on your server, then you should use code 302 (or alternately, 307) to ensure that subsequent requests are still sent to the original URL in case you ever decide to change/update your dynamic code to do something different.

- 54,026
- 20
- 135
- 176