Código de status HTTP · Redirecionamento (3xx)
307 Temporary Redirect
O status 307 Temporary Redirect significa que o recurso está temporariamente na URL do Location e o cliente deve repetir o pedido lá com o mesmo método e corpo. É comum encontrá-lo no DevTools do Chrome como "307 Internal Redirect", que é o próprio navegador trocando http:// por https:// por causa do HSTS, antes de qualquer pedido sair da sua máquina.
| Classe | 3xx, Redirecionamento |
|---|---|
| Definido em | RFC 9110 §15.4.8 |
| Pode ir para o cache por padrão | Só com Cache-Control ou Expires explícitos |
| Pode repetir o pedido | Repita o mesmo pedido, com mesmo método e corpo, no Location |
| Cabeçalhos relevantes |
|
O que significa o 307
A RFC 9110, seção 15.4.8, acrescenta uma regra ao 302: o cliente não pode mudar o método quando segue o redirecionamento sozinho. Um POST com corpo JSON é reenviado como POST, com o mesmo corpo, para o novo endereço. O cliente deve continuar usando a URL original nos próximos pedidos, e sem cabeçalhos de cache explícitos o redirecionamento não fica guardado.
O Chrome também mostra como 307 os redirecionamentos que faz internamente. Quando um site está na lista HSTS, a URL http:// é reescrita para https:// dentro do navegador, e o DevTools exibe um "307 Internal Redirect" sintético com o cabeçalho Non-Authoritative-Reason: HSTS. Nenhum servidor enviou essa resposta, então não há nada a corrigir no servidor.
Vários frameworks usam 307 por padrão: redirect() e NextResponse.redirect() no Next.js, RedirectResponse no FastAPI e o redirecionamento automático de barra final do Starlette. Por isso é fácil publicar um 307 onde a intenção era um redirecionamento permanente.
Quando usar
- Mandar temporariamente tráfego com POST ou PUT para outro servidor: um endpoint regional, uma instância de manutenção, outro host de upload.
- Qualquer redirecionamento temporário em API, onde trocar POST por GET em silêncio quebraria a chamada.
- Mudanças curtas de páginas comuns também; em pedidos GET ele se comporta igual ao 302.
Causas comuns
Se você está visitando o site
- O DevTools mostra "307 Internal Redirect": a política HSTS do navegador trocou http:// por https://, o que é esperado.
- Um site que responde todo pedido com 307 para uma página de login, de região ou de consentimento que quer mostrar antes.
Se você administra o servidor
- Padrões de framework: uma mudança definitiva feita com redirect() ou NextResponse.redirect() do Next.js sai como 307, e os buscadores tratam como temporária.
- FastAPI e Starlette redirecionam /itens para /itens/ (ou o contrário) com 307 quando a rota foi declarada do outro jeito, dobrando o número de pedidos dos clientes da API.
- Redirecionamento de http para https em tráfego de API: funciona com 307, mas custa uma ida e volta por chamada, e o primeiro pedido, com corpo e tudo, já passou pela rede sem criptografia.
Como resolver
Se você está visitando o site
- Nada a fazer no redirecionamento interno do HSTS. Para um loop de 307, apague os cookies do site e tente de novo.
Se você administra o servidor
- Use permanentRedirect() ou um redirect no next.config com permanent: true quando a mudança for definitiva; os dois enviam 308.
- Declare as rotas da API com o caminho exato que os clientes chamam, ou crie o app com FastAPI(redirect_slashes=False), para acabar com o salto extra.
- Aponte os clientes da API direto para https:// e ative o HSTS em vez de depender de redirecionamento.
Como enviar um 307
// Uploads go to the EU host while the main one is being migrated
app.post('/uploads', (req, res) => {
res.redirect(307, 'https://upload-eu.example.com/uploads');
});// app/uploads/route.ts
export async function POST() {
return Response.redirect('https://upload-eu.example.com/uploads', 307);
}
// redirect() from next/navigation and NextResponse.redirect()
// also default to 307.mux.HandleFunc("POST /uploads", func(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "https://upload-eu.example.com/uploads", http.StatusTemporaryRedirect) // 307
})from fastapi import FastAPI
from fastapi.responses import RedirectResponse
app = FastAPI()
@app.post("/uploads")
def uploads():
# 307 is RedirectResponse's default; spelled out for clarity
return RedirectResponse("https://upload-eu.example.com/uploads", status_code=307)location /uploads {
return 307 https://upload-eu.example.com$request_uri;
}Costuma ser confundido com
- 307 vs 302
- Os dois são temporários; o 302 deixa o cliente trocar POST por GET e o navegador troca, enquanto o 307 proíbe mudar o método.
- 307 vs 308
- O 308 é o gêmeo permanente: mesma regra de manter o método, mas pode ir para o cache por padrão e o Google trata como mudança definitiva.
- 307 vs 303
- O 303 obriga o pedido seguinte a ser um GET numa página de resultado; o 307 obriga que seja o mesmo pedido de novo.
Perguntas frequentes
- O que é "307 Internal Redirect" no Chrome?
- É um redirecionamento que o próprio Chrome faz, geralmente porque o site está na lista HSTS, então http:// vira https:// antes de sair qualquer pedido pela rede. O DevTools marca com Non-Authoritative-Reason: HSTS. O servidor nunca enviou esse 307 e não há nada para corrigir.
- Qual a diferença entre 302 e 307?
- Os dois indicam mudança temporária. Com o 302, o navegador troca POST por GET e descarta o corpo; com o 307 ele é obrigado a repetir o POST com o mesmo corpo. Em pedidos GET os dois funcionam igual.
- O redirecionamento 307 prejudica o SEO?
- O Google trata o 307 como equivalente ao 302, um redirecionamento temporário, e mantém a URL original nos resultados. Isso é o certo para mudanças temporárias e um erro para as definitivas, que devem usar 301 ou 308.
- Por que o Next.js responde 307 no meu redirecionamento?
- O redirect() de next/navigation e o NextResponse.redirect() usam 307 por padrão, e o redirect() dentro de uma Server Action responde 303. Use permanentRedirect() ou permanent: true no next.config para ter um 308.
Revisado em por Arielton Oberek.