303 redirect
A 303 tells the client to fetch a different resource with a GET request, regardless of the original method. It powers the POST-redirect-GET pattern: after form submission, redirect to results so refresh never resubmits.
Why it matters
The 303 is the semantically correct answer to a real user question: if I submit a form and get a result, will refreshing the page resubmit it? A 303 ensures the answer is no. In practice, most frameworks emit a 302 after POST and browsers treat it the same way for form submissions. That's why 303 is rare in the wild. Seeing one usually means a deliberate, standards-aware backend.
How it works
When a form is submitted, the browser sends a POST request. The server responds with a 303 status and a Location header pointing to a results page. The browser automatically converts this to a GET request to the target URL. Later, if the user refreshes or uses back/forward, the browser only re-sends the GET request, never the original form data.
This is the POST-Redirect-GET (PRG) pattern. The 303 explicitly mandates the method change to GET, whilst a 302 merely permits it as a client choice. In HTML form processing, both achieve the same result. But only 303 is semantically correct.
What doesn't matter
A 303 in a normal navigation chain isn't inherently wrong, but it's unusual. Most content moves use 301 or 302. A 303 appearing on a page that isn't a form result may signal a framework using the wrong status code, but it won't break the chain or cause ranking loss.
The 303 doesn't affect SEO. Search engines don't POST to pages, so they never encounter this redirect pattern. It's purely a browser and form-handling concern.
Code example
After a form submission, respond with a 303 redirect to a results page.
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Process the form
$result_id = save_form_data($_POST);
header('HTTP/1.1 303 See Other');
header('Location: /results/' . $result_id);
exit;
}
The browser receives the 303 and automatically issues a GET request:
GET /results/42
If the user refreshes the results page, only the GET request repeats. The POST never resubmits.
What to avoid: returning 200 after a POST without redirecting.
// Don't do this; refreshing will resubmit the form
echo render_results($_POST);
How Scalpel shows it
A 303 hop renders like any server hop with its status line on the connector. Because 303 is rare in normal navigation chains, its appearance is worth investigating. It usually signals something deliberate on the server side.