303 See Other
The server is redirecting the client to a different resource, and the client MUST use a GET request to fetch it.
Meaning & Description
The defining characteristic of a 303 redirect is that it strictly instructs the client to change the HTTP method to `GET` for the subsequent request, regardless of what method was originally used. This makes it the backbone of the POST/Redirect/GET (PRG) web development pattern, which prevents users from accidentally resubmitting forms if they refresh the page.
Common Causes
- Implementing the POST/Redirect/GET (PRG) pattern.
- Form submissions returning a success view.
- Redirecting to a status polling endpoint after triggering a long-running task.
How to fix a 303 error
- Ensure the URL in the `Location` header is capable of handling a `GET` request.
- Verify that session state (like success flash messages) is preserved across the redirect, usually via cookies or server-side sessions.
- If the client incorrectly maintains a `POST` request on redirect, check if they are using an outdated HTTP client, or if you accidentally sent a `307 Temporary Redirect` instead.
Browser & SEO Behaviour
Browser Behavior
Upon receiving a 303, the browser will immediately drop the original request body and method, and issue a fresh `GET` request to the URL in the `Location` header. This prevents the "Confirm Form Resubmission" dialog if the user clicks refresh.
SEO Impact
Search engines rarely encounter 303s as they do not typically submit forms or execute POST requests. If they do, they will index the target URL, not the redirecting URL.
CDN Behavior
CDNs do not cache 303 responses, as they are typically the result of a state-changing POST request.
Code Examples
HTTP/1.1 303 See Other
Date: Mon, 12 Sep 2026 12:00:00 GMT
Location: /checkout/success
Content-Length: 0app.post('/form-submit', (req, res) => {
// Process the form data here
saveData(req.body);
// Redirect to success page using 303 to force a GET request
res.redirect(303, '/success');
});from fastapi import FastAPI, Form
from fastapi.responses import RedirectResponse
app = FastAPI()
@app.post("/submit")
def submit_form(name: str = Form(...)):
# Process data
# Use 303 to ensure the browser uses GET for the /success route
return RedirectResponse(url="/success", status_code=303)func submitHandler(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodPost {
// Process POST data...
// Redirect using 303 See Other
http.Redirect(w, r, "/success", http.StatusSeeOther)
}
}[HttpPost("submit")]
public IActionResult SubmitForm([FromForm] FormData data)
{
// Save data...
// Redirect to a GET endpoint
return RedirectPreserveMethod("/success"); // Note: In ASP.NET, standard Redirect() does a 302. For a true 303, you might need a custom ActionResult or use StatusCode(303).
// Better: return StatusCode(303, new { Location = "/success" });
}curl -X POST -d "name=Alice" -I http://example.com/submit
# Adding -L follows the redirect, automatically switching to GET
curl -X POST -d "name=Alice" -I -L http://example.com/submitRaw HTTP Response Example
HTTP/1.1 303 See Other
Location: https://store.example.com/checkout/success
Content-Length: 0
Connection: closeReal-world Examples
Frequently Asked Questions
What is the POST/Redirect/GET (PRG) pattern?
It is a web development design pattern. Instead of returning HTML directly after a POST request, the server returns a 303 redirect. The browser then makes a GET request to fetch the HTML. This prevents the user from accidentally resubmitting the form if they refresh the page.
Why use 303 instead of 302 for the PRG pattern?
While 302 often works because early browsers incorrectly changed POSTs to GETs, 303 is the explicitly correct standard for this behavior. It guarantees that any compliant client will drop the POST body and switch to a GET request.
Does a 303 redirect preserve the request body?
No, absolutely not. The defining feature of a 303 redirect is that it drops the request body and forces a standard GET request.
Can I use a 303 redirect after a GET request?
While technically valid, it is semantically incorrect. 303 means "the result of your action is elsewhere." For redirecting a standard GET request, you should use 301, 302, or 307.
How do I pass data to the redirected page in a PRG flow?
Since the request body is dropped, you must pass data via URL query parameters, cookies, or server-side session storage (often called "flash messages").
Did You Know?
The 303 status code was specifically invented in HTTP/1.1 to formalize the behavior that early web browsers were already doing illegally with the 302 status code.
Modern frontend frameworks like Next.js and Remix rely heavily on the PRG pattern and 303 redirects for their server actions and form mutations.
Developer Tips
- Always use 303 for form submission redirects. It is the gold standard for preventing the dreaded "Are you sure you want to resubmit this form?" browser dialog.
- Use "flash" session storage to pass success/error messages across the 303 redirect boundary.
- If you need to redirect a POST request but WANT the client to maintain the POST method and body, use 307 Temporary Redirect instead of 303.
Interview Questions
These are questions you might face in a backend or API design interview that touch on HTTP 303.
Explain the POST/Redirect/GET pattern and which HTTP status code enables it.
The PRG pattern prevents duplicate form submissions. When a server successfully processes a POST request, it replies with a 303 See Other redirect. The browser then issues a GET request to the new URL. If the user hits refresh, they only refresh the GET request, not the POST.
What is the exact difference between 303 See Other and 307 Temporary Redirect?
303 explicitly forces the client to change the request method to GET and drop the request body. 307 explicitly forces the client to maintain the original HTTP method (e.g., POST) and keep the request body intact.
Why shouldn't you pass sensitive data in the query string during a 303 redirect?
Because the new URL (which uses GET) will be saved in the browser's history, server logs, and potentially referer headers. Sensitive data should be kept in a server-side session during the redirect.
Common Interview Mistakes
- Failing to connect the 303 status code to the PRG (POST/Redirect/GET) pattern.
- Thinking that 303 preserves the request payload.
- Recommending 303 for permanent domain migrations (which should be 301).