While both HTTP 302 (Found) and 303 (See Other) are redirection status codes, their behavioral differences are crucial for proper REST API design and web application architecture.
// 302 Found response example
HTTP/1.1 302 Found
Location: /new-location
// 303 See Other response example
HTTP/1.1 303 See Other
Location: /different-resource
302 Found is appropriate when:
- Performing temporary URL redirects during maintenance
- Handling A/B testing scenarios
- Implementing short-lived vanity URLs
303 See Other should be used when:
- Responding to POST requests that require a separate GET
- Implementing the Post/Redirect/Get pattern
- Preventing form resubmission issues
// Express.js 302 implementation
app.get('/old', (req, res) => {
res.status(302).redirect('/new-endpoint');
});
// Django 303 implementation
def form_submit(request):
if request.method == 'POST':
# Process form data
return HttpResponseRedirect('/confirmation', status=303)
Modern browsers handle these codes differently:
- 302: Subsequent requests may use original method
- 303: Forces subsequent requests to use GET
- Never use 302 for POST responses - this can cause accidental resubmissions
- Always include absolute URLs in Location headers
- Consider 307 for true temporary redirects that preserve method
Search engines treat these differently:
- 302 passes minimal link equity
- 303 doesn't pass any link equity
- Neither should be used for permanent redirects (use 301 instead)
While both HTTP 302 (Found) and 303 (See Other) are redirection status codes, their semantic meaning and intended use cases differ significantly in the HTTP/1.1 specification:
// 302 response example
HTTP/1.1 302 Found
Location: /new-location
// 303 response example
HTTP/1.1 303 See Other
Location: /confirmation-page
The key technical differences according to RFC 2616:
- 302 Found: The requested resource temporarily resides under a different URI. The client should continue to use the original URI for future requests.
- 303 See Other: The response to the request can be found under a different URI and should be retrieved using a GET method on that resource.
When to Use 302
Perfect for temporary redirects during maintenance or A/B testing scenarios:
// Node.js Express example
app.post('/checkout', (req, res) => {
if (isMaintenanceMode) {
res.status(302).redirect('/maintenance');
} else {
processCheckout(req, res);
}
});
When to Use 303
Essential for POST-Redirect-GET pattern to prevent form resubmission:
// PHP example after form submission
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Process form data
header('HTTP/1.1 303 See Other');
header('Location: /thank-you');
exit;
}
Modern browsers handle these codes differently:
- 302: Preserves original request method (POST remains POST)
- 303: Always converts subsequent request to GET
Proper usage in API design:
# Python Flask API example
@app.route('/api/orders', methods=['POST'])
def create_order():
new_order = process_order(request.json)
if request.accept_mimetypes.accept_json:
return jsonify(new_order), 201
else:
return redirect(url_for('order_status', id=new_order.id), code=303)
Search engines treat these differently:
- 302 passes little to no link equity
- 303 is treated as a true redirection (similar to 301 for SEO purposes)
- Using 302 for POST requests where you want to prevent resubmission
- Assuming 303 will preserve the original request method
- Not considering caching implications (302 responses might be cached)