303 See Other: The POSTโRedirectโGET Pattern
The Post/Redirect/Get (PRG) Pattern
Without PRG, if a user submits a form and then refreshes the page, the browser will resend the same POST request, potentially duplicating the action (e.g., placing two orders). The PRG pattern solves this:
- User submits a form via POST.
- Server processes the request and then responds with 303 See Other, with a
Locationheader pointing to a result page. - Browser follows the redirect using a GET request to the result page.
- If the user refreshes, only the GET is repeated, not the POST.
Example Flow
| Step | Direction | HTTP Message |
|---|---|---|
| 1 | Client โ Server | POST /order HTTP/1.1 |
| 2 | Server โ Client | HTTP/1.1 303 See Other |
| 3 | Client โ Server | GET /order-confirmation/456 HTTP/1.1 |
| 4 | Server โ Client | HTTP/1.1 200 OK |
303 vs. 302 vs. 307
| Status | Method After Redirect | Use Case |
|---|---|---|
| 303 See Other | Always GET | After POST to show result (PRG pattern). |
| 302 Found | May change to GET | General temporary redirect (legacy). |
| 307 Temporary Redirect | Preserved (POST โ POST) | Temporary redirect with method preservation. |
SEO Implications
- Temporary โ 303 is a temporary redirect, so search engines do not transfer PageRank.
- Not for permanent moves โ use 301 or 308 for permanent changes.
- Safe for forms โ 303 is the recommended way to handle form submissions to avoid duplicate content issues.
When Not to Use 303
- For permanent redirects โ use 301 or 308.
- When you need to preserve the original method โ use 307.
- For GET requests โ 303 is intended for POST/PUT. For GET, use 302 or 307.
- When you want the client to cache the redirect โ 303 is not cached by default.
Frequently Asked Questions
Is 303 See Other the same as 302?
No. While both are temporary redirects, 303 explicitly changes the method to GET, while 302 may or may not (browserโdependent). 303 is the correct choice for the PRG pattern.
Can I use 303 for AJAX requests?
Yes, but the browser's automatic redirect handling for AJAX may differ. For fetch/XHR, the redirect is followed automatically, but you may need to handle it in your code. Some libraries allow you to disable automatic redirects and handle them manually.
Is 303 cached?
By default, 303 responses are not cached because they are temporary. You can add Cache-Control headers if you want to cache them for a short period.