Cos'è il redirect 307
Il 307 Temporary Redirect è un codice di stato HTTP introdotto in HTTP/1.1 (RFC 2616) e rifinito nella RFC 9110. Dice al client: «La risorsa richiesta è temporaneamente disponibile a un URL diverso. Ripeti la richiesta lì con lo stesso metodo e lo stesso body». La parola chiave è «stesso metodo»: se un utente ha inviato un form POST, il 307 impone al browser di inviare un altro POST al nuovo URL invece di passare silenziosamente a GET.
È esattamente questo che distingue il 307 dal 302. Mentre la specifica HTTP richiedeva formalmente al 302 di preservare il metodo, storicamente la maggior parte dei browser cambiava POST in GET alla ricezione di un 302. Gli autori delle RFC hanno documentato questo «bug» come comportamento di fatto del 302, e il 307 è stato introdotto come codice con garanzia di preservazione del metodo.
307 vs 302 vs 308 vs 301: differenze chiave
I quattro codici di redirect differiscono lungo due assi: permanenza e preservazione del metodo HTTP.
- 301 Moved Permanently — redirect permanente, trasferisce il valore dei link. Il metodo dovrebbe tecnicamente essere preservato, ma i browser degradano POST→GET (comportamento ereditato da HTTP/1.0).
- 302 Found (temporaneo) — redirect temporaneo, nessun trasferimento di valore. Il metodo è di fatto cambiato POST→GET nella maggior parte dei browser.
- 307 Temporary Redirect — redirect temporaneo, nessun trasferimento di valore. Il metodo è rigorosamente preservato (POST resta POST).
- 308 Permanent Redirect — redirect permanente, trasferisce il valore dei link. Il metodo è rigorosamente preservato. L'equivalente del 301 amico di API e form.
Quando usare il 307
- Upgrade a HTTPS per le richieste POST: quando un sito accetta form via HTTP e deve reindirizzarli a HTTPS senza perdere il body della richiesta.
- Redirect API durante la migrazione temporanea di endpoint: quando un client invia PUT/PATCH/DELETE e devi instradare temporaneamente il traffico verso un altro host o un'altra versione dell'API.
- Load balancing e failover: quando un nodo cade, instrada le richieste a un server di standby preservando il metodo originale.
- Redirect geografici: instrada temporaneamente gli utenti a una versione regionale preservando il metodo POST per gli invii dei form.
- A/B testing sui form: instrada temporaneamente una parte del traffico POST a una variante di test senza cambiare il metodo.
- Finestre di manutenzione: preserva le richieste POST mentre l'URL principale è in manutenzione.
Redirect 307 e SEO
Dal punto di vista dei motori di ricerca, il 307 è un redirect temporaneo. Google e Bing non trasferiscono il valore dei link (PageRank) attraverso il 307: l'URL originale resta indicizzato e la destinazione non ottiene autorità aggiuntiva. Se un 307 resta attivo abbastanza a lungo (diversi mesi), Google può rivalutarlo come permanente — analogamente a come tratta un 302 di lunga durata.
Nella pratica il 307 compare negli audit SEO in due contesti: i redirect HTTPS (corretti per i POST, ma per le normali pagine GET è preferibile il 301) e le catene di redirect. Ogni hop in più in una catena — sia 307, 302 o 301 — aggiunge latenza e può danneggiare l'LCP. Limita le catene a non più di due hop.
Come configurare il redirect 307
Esempi per gli ambienti server più comuni:
# Nginx: temporary redirect with method preservation
server {
listen 80;
server_name example.com;
# All HTTP traffic → HTTPS (307 preserves POST body)
return 307 https://example.com$request_uri;
}
# Specific path
location /api/v1/ {
return 307 https://example.com/api/v2/;
}# Apache (.htaccess)
# Temporary redirect for a single URL
Redirect 307 /old-endpoint https://example.com/new-endpoint
# or via mod_rewrite
RewriteEngine On
RewriteRule ^api/v1/(.*)$ https://example.com/api/v2/$1 [R=307,L]// Next.js (next.config.js) — temporary redirect
module.exports = {
async redirects() {
return [
{
source: '/api/v1/:path*',
destination: '/api/v2/:path*',
permanent: false, // permanent: false → 307
},
];
},
};<?php
// PHP: explicit 307
http_response_code(307);
header('Location: https://example.com/new-endpoint');
exit();
?># Verify via curl — confirm the response is exactly 307
curl -I -X POST https://example.com/old-endpoint
# HTTP/2 307
# location: https://example.com/new-endpoint