56

A common scenario for a web app is to redirect after a POST that modifies the database. Like redirecting to the newly created database object after the user creates it.

It seems like most web apps use 302 redirects, but 303 seems to be the correct thing to do according to the specification if you want the url specified in the redirect to be fetched with GET. Technically, with a 302, the browser is supposed to fetch the specified url with the same method that the original url was fetched with, which would be POST. Most browsers don't do that though.

302 - https://www.rfc-editor.org/rfc/rfc9110.html#name-302-found

303 - https://www.rfc-editor.org/rfc/rfc9110.html#name-303-see-other

So should I be using 302 or 303?

fcrozatier
  • 350
  • 3
  • 9
Kyle
  • 21,377
  • 37
  • 113
  • 200
  • 2
    Related: [Difference between HTTP redirect codes](http://stackoverflow.com/questions/4764297/), [HTTP: POST request receives a 302, should the redirect-request be a GET?](http://stackoverflow.com/questions/4764297/) – Piotr Dobrogost Nov 27 '11 at 20:31
  • As noted by @porneL, RFC 2616 dates from 1999, and further is now officially '[dead](https://www.mnot.net/blog/2014/06/07/rfc2616_is_dead)', according to the chair of the IETF HTTP Working Group (replaced by RFCs 7230 through 7235). – ChrisV Jan 21 '15 at 09:26

5 Answers5

60

The correct one is 303.

I use it and haven't found any compatibility problems with UAs newer than Netscape 4 (1998, released 17 years ago).

If you use 302, you're risking that UA will re-send POST to the new URL instead of switching to GET.

Still, if you're worried about HTTP/1.0 clients (which don't support vhosts and probably won't be able to access your page anyway) then you should include HTML with link to the new page in body of the 303 response (web servers like Apache do that already).

Kornel
  • 97,764
  • 37
  • 219
  • 309
  • 5
    While 303 is technically correct (and is what I use), modern browsers (I just tried it on Chrome 26) *still* don't follow the spec for a 302 response to a POST, so it seems on the modern web 302 === 303. – Raman Apr 03 '13 at 18:41
  • 1
    @Raman: True, I don't think there will be any time soon where we can start to use the new definition of 302 on the World Wide Web, if ever (that's a very brave browser vendor). The HTTP specification can be followed as intended in a 'walled-garden' by non-Web UAs though, so redirecting POSTs it's not a complete lost cause. – Lee Kowalkowski Feb 24 '14 at 11:57
  • `HTTP/1.0` clients are not that uncommon, actually. For example `wget` got his `HTTP/1.1` support only in 2011, and it hasn't made to Debian stable release yet. If you create an API and you mean it to be portable and bot-friendly, design your application for `HTTP/1.0`. – rr- Sep 07 '14 at 06:25
  • 1
    @rr- there's a massive difference between modern clients avoiding some HTTP/1.1 features and declaring they use HTTP/1.0, and real old HTTP/1.0 clients from 1999. For example HTTP/1.0 didn't support virtual hosts, so such client would fail to open almost any page on the web today. – Kornel Sep 07 '14 at 16:04
22

Depends.
303 and 307 responses were added in HTTP1.1.
So client agents that are strictly compliant to HTTP1.1 RFC should be fine with a 303 response.
But there can be agents that are not fully conformant or are HTTP1.0 compliant and will not be able to handle the 303.
So to be sure that the response of your application can be handled gracefully by the majority of client implementations I think 302 is the safest option.
Excerpt from RFC-2616:

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.

Community
  • 1
  • 1
Cratylus
  • 52,998
  • 69
  • 209
  • 339
  • 2
    Yep, but I still frequently find (usually corporate) proxies that aren't fully 1.1 compliant. I'd also err on the side of caution. – Michael May 08 '12 at 10:06
  • 10
    @Mikaveli proxies don't execute redirects, so that is irrelevant. It only matters for UAs, and if you support NN4/IE4 then 303 status is the least of your problems :) – Kornel May 16 '12 at 15:56
  • @porneL - Many corporate proxies _do_ cache response codes etc. though - especially things like moved temporarily / permanently. – Michael May 17 '12 at 08:13
  • 5
    @Mikaveli in worst case just mark response as non-cacheable? I really doubt that people would tolerate a proxy that is so broken. Caching temporary redirects would break lots of websites (possibly anything with redirects before/after login). – Kornel May 23 '12 at 22:40
9

In most server-side languages the default redirection mechanism uses 302:

  • Java response.sendRedirect(..) uses 302
  • ASP.NET response.Redirect(..) uses 302
  • PHP header("Location: ..") uses 302
  • RoR redirect_to uses 302
  • etc..

So I'd prefer this, rather than setting status and headers manually.

Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
  • 3
    Ye gods, I had no idea PHP's `header()` also does some voodoo besides sending the given header data. Checked with the docs, +1 for bringing that up – Kos Jun 26 '13 at 15:53
  • 2
    and ExpressJS `res.redirect(url)` uses 302 by default – Andy Mar 18 '14 at 12:28
6

In theory, you (and all the world) should be using 303 as you have noted. But also, most browsers react to a 302 like they should react to a 303. So, overall, it seems that it won't matter if you send 302 or 303. In the link you provided for the 303 specification, theres an interesting note:

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.

It's important to note the pre-HTTP/1.1 user agents, so maybe this was important a while ago, but I don't believe it is the case now.

So, all in all, it's up to you (I could bet whatever you want that browsers won't change their behavior against 302 statuses never, for fear of breaking the internet for their users).

Carlos Campderrós
  • 22,354
  • 11
  • 51
  • 57
4

When providing the location of a new resource created by a POST request, 201 ("Created") is an appropriate response.

HTTP/1.1: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.2

Atom Publishing Protocol: https://www.rfc-editor.org/rfc/rfc5023#section-5.3

This does mean that a web browser probably won't redirect to the new URL, though; the user has to follow a link to get to the new item (this link can be provided in the body of the response, as well as in the Location header).

Community
  • 1
  • 1
Alf Eaton
  • 5,226
  • 4
  • 45
  • 50