An overview of 301, 302 and 307
The RFC 7231, the current reference for semantics and content of the HTTP/1.1 protocol, defines the 301 (Moved Permanently) and 302 (Found) status code, that allows the request method to be changed from POST to GET. This specification also defines the 307 (Temporary Redirect) status code that doesn’t allow the request method to be changed from POST to GET.
See more details below:
6.4.2. 301 Moved Permanently
The
301(Moved Permanently) status code indicates that the target
resource has been assigned a new permanent URI and any future
references to this resource ought to use one of the enclosed URIs. […]Note: For historical reasons, a user agent MAY change the request
method fromPOSTtoGETfor the subsequent request. If this
behavior is undesired, the307(Temporary Redirect) status code
can be used instead.
6.4.3. 302 Found
The
302(Found) status code indicates that the target resource
resides temporarily under a different URI. Since the redirection
might be altered on occasion, the client ought to continue to use the
effective request URI for future requests. […]Note: For historical reasons, a user agent MAY change the request
method fromPOSTtoGETfor the subsequent request. If this
behavior is undesired, the307(Temporary Redirect) status code
can be used instead.
6.4.7. 307 Temporary Redirect
The
307(Temporary Redirect) status code indicates that the target
resource resides temporarily under a different URI and the user agent
MUST NOT change the request method if it performs an automatic
redirection to that URI. Since the redirection can change over time,
the client ought to continue using the original effective request URI
for future requests. […]Note: This status code is similar to
302(Found), except that it
does not allow changing the request method fromPOSTtoGET. This
specification defines no equivalent counterpart for301(Moved
Permanently) (RFC 7238, however, defines the status code308
(Permanent Redirect) for this purpose).
Changing the request method from POST to GET
The “historical reasons” in which a user agent may change a request from POST to GET is explained in an Eric Lawrence’s post from the IEInternals blog, dated from 19 August 2011.
The post quotes the definition of the status code 301 from the obsolete RFC 1945, published in May 1996, which defined the HTTP/1.0. The key part from that quote is:
Note: When automatically redirecting a
POSTrequest after receiving a301status code, some existing user agents will erroneously change it into aGETrequest.
Then the author continues:
[…] those “user agents” referred to in this remark included the popular browsers of the day, including Netscape Navigator and Internet Explorer. Arguably, this behavior is exactly what most websites wanted — after a successful
POST, send the user to a different URL to show them something else. However, thePOST-converted-to-GETbehavior isn’t what the authors of HTTP had intended.
The need for 308
The RFC 7238 has been created to define the 308 (Permanent Redirect) status code, that is similar to 301 (Moved Permanently) but does not allows the request method to be changed from POST to GET.
The 308 status code is now defined by the RFC 7538 (that obsoleted the RFC 7238).
3. 308 Permanent Redirect
The
308(Permanent Redirect) status code indicates that the target
resource has been assigned a new permanent URI and any future
references to this resource ought to use one of the enclosed URIs.
Clients with link editing capabilities ought to automatically re-link
references to the effective request URI to
one or more of the new references sent by the server, where possible. […]Note: This status code is similar to
301(Moved Permanently),
except that it does not allow changing the request method from
POSTtoGET.
Se we have the following:
+-----------+-----------+
| Permanent | Temporary |
+------------------------------------------------------------+-----------+-----------+
| Allows changing the request method from POST to GET | 301 | 302 |
+------------------------------------------------------------+-----------+-----------+
| Doesn't allow changing the request method from POST to GET | 308 | 307 |
+------------------------------------------------------------+-----------+-----------+
Choosing the most suitable status code
Michael Kropat put together a set of decision charts that helps to determine the best status code for each situation. See the following for 2xx and 3xx status codes:
