259

What's the difference between HTTP 301 and 308 status codes?

  • 301 (Moved Permanently): This and all future requests should be directed to the given URI.

  • 308 (Permanent Redirect): The request and all future requests should be repeated using another URI.

They seem to be similar.

cassiomolin
  • 124,154
  • 35
  • 280
  • 359
Alexander Drobyshevsky
  • 3,907
  • 2
  • 20
  • 17

2 Answers2

447

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 from POST to GET for the subsequent request. If this behavior is undesired, the 307 (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 from POST to GET for the subsequent request. If this behavior is undesired, the 307 (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 from POST to GET. This specification defines no equivalent counterpart for 301 (Moved Permanently) (RFC 7238, however, defines the status code 308 (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 POST request after receiving a 301 status code, some existing user agents will erroneously change it into a GET request.

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, the POST-converted-to-GET behavior 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 POST to GET.

So 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:

Picking a 2xx or 3xx status code

saw303
  • 8,051
  • 7
  • 50
  • 90
cassiomolin
  • 124,154
  • 35
  • 280
  • 359
  • 19
    Given that the question was specifically about the destinction between 301 and 308, could you give some more explanation on: _"does not allows the request method to be changed from `POST` to `GET`"_? Would it mean dat a posted form cannot be processed, but a fresh new form could be serverd and then be posted on a next request? – R. Schreurs Aug 23 '18 at 07:29
  • 6
    This draft specification (https://tools.ietf.org/id/draft-hunt-http-rest-redirect-00.html) suggests that ReSTful services should use 308 even for GETs. "HTTP redirection codes 301-306 SHOULD NOT be used unless the service provider is aware the client is in fact a user-agent." However this is only a draft. I'm not sure if/when it will be accepted. – Bruce Adams Nov 22 '18 at 15:45
  • 4
    This post, [the-definitive-guide-to-get-vs-post](https://blog.teamtreehouse.com/the-definitive-guide-to-get-vs-post), clarifies why allowing a `POST` (safe) request to be *changed* into a to `GET` (unsafe in that data is passed by adding it to the url - and urls can be saved - including passwords) request can be a security issue, and generally should be avoided, unless you *know* it to be safe to change. These days it seems that it's generally supported and preferred to use 307, 308 over 301, 302. But you should verify. – SherylHohman Jun 18 '20 at 19:52
  • 3
    Mnemonic `308` is like a sideways infinity, so Permanent redirect, and also never change the request Method - it is also a permanent, fixed request type. Then ,`307` is `1` step below - permanent/keep request Method (Get/Post), but redirect to a temp location: 7 - looks like "left turn" or temp detour, and 7 is also similar looking to k, so "keep" the request method. – SherylHohman Jun 18 '20 at 20:01
  • You forgot to mention [Resume Incomplete](https://web.archive.org/web/20151013212135/http://code.google.com/p/gears/wiki/ResumableHttpRequestsProposal#Status_Code:_308_Resume_Incomplete). – Knu Jul 13 '20 at 13:23
  • @Knu That's not a [standard status code for HTTP](https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml), at least not with that meaning: `308` has been standardised as _Permanent Redirect_. – cassiomolin Jul 13 '20 at 14:31
  • 1
    @cassiomolin What does "historical reasons" mean here in _"For historical reasons, a user agent MAY change the request method from POST to GET for the subsequent request. If this behavior is undesired, the 307 (Temporary Redirect) status code can be used instead."_ – yogesh puttaswamy Sep 02 '22 at 11:05
  • @yogeshputtaswamy I think old HTTP RFCs will give you the context. See [this](https://www.ietf.org/rfc/rfc2616.html#section-10.3.3), [this](https://www.rfc-editor.org/rfc/rfc2068.html#section-10.3.3), and [this](https://www.rfc-editor.org/rfc/rfc1945.html#page-35). – cassiomolin Sep 02 '22 at 18:49
  • @yogeshputtaswamy By the way, I need to update my answer, as the RFCs 7130-35 have been obsoleted by a new set of RFCs: 9110-12. – cassiomolin Sep 02 '22 at 18:50
  • @cassiomolin ... Didn't get what is the meaning of 'For historical reasons, a user agent MAY change the request method from POST to GET for the subsequent request.' in RFC Document. What does this 'historical reasons' mean? – yogesh puttaswamy Sep 30 '22 at 04:33
  • @yogeshputtaswamy This [post](https://web.archive.org/web/20190109001229/https://blogs.msdn.microsoft.com/ieinternals/2011/08/19/http-methods-and-redirect-status-codes/) from the IEInternals blog dated 19 August 2011 should give you a good context on this. – cassiomolin Sep 30 '22 at 11:57
  • @yogeshputtaswamy I updated my answer with these details. – cassiomolin Sep 30 '22 at 15:34
  • For completeness it would make sense to mention the status `303 See Other`, which explicitly requires the request to be changed to `GET`, for those cases where the request was processed and then the next page to display should be fetched from other URL (it is on the diagram, but not described in the text). – Jan Hudec Jan 17 '23 at 13:38
1

Mentioning below common observed client behavior when redirecting using 3xx status codes. Its best to test these scenarios with your HTTP client as it may not follow the same path as mentioned below.

301

  • HTTP Method will be changed to GET. Not just POST but also DELETE, PUT, PATCH etc. (except for HEAD).
  • While redirecting, most headers will be retained but certain sensitive headers like Authorization will be removed.
  • Same domain, different scheme redirects (eg: http to https redirect) will retain sensitive headers as well.
  • Body may or may not be removed. Since method is changed to GET, this will not matter in most cases.
  • Indicates that search engines may update their links to the resource.

302

  • Same as 301 but for temporary redirection. A browser redirects to this page but search engines don't update their links to the resource.

308

  • HTTP Method will not change.
  • Most headers will be retained but certain sensitive headers like Authorization will be removed. (exception with same domain redirects)
  • Body will be retained.
  • Search engines may update their links to the resource.

307

  • Same as 308 but for temporary redirection. A browser redirects to this page but search engines don't update their links to the resource.

303

  • This is useful when you want to give an answer to a PUT or POST method that is not the uploaded resources, but a confirmation message (like "You successfully uploaded XYZ") using a GET redirection. The result of the original HTTP request can be found at a different URL which can be separately identified, bookmarked, and cached, independent of the original request. Also, refresh of the result page doesn't re-trigger the POST/PUT operation. Some apps use 302 Found HTTP response for this purpose.
  • All HTTP Method's except HEAD will be changed to GET.
  • While redirecting, most headers will be retained but certain sensitive headers like Authorization will be removed. (exception with same domain redirects)

300

  • Multiple choices redirect status response code indicates that the request has more than one possible response and the client should choose one of them.
ns15
  • 5,604
  • 47
  • 51