Código de status HTTP · Redirecionamento (3xx)
302 Found
O redirecionamento 302 (Found) significa que o recurso está temporariamente na URL do cabeçalho Location e que o cliente deve continuar usando a URL original no futuro. É o que a maioria dos frameworks envia por padrão num redirecionamento, geralmente para mandar o visitante ao login e de volta.
| Classe | 3xx, Redirecionamento |
|---|---|
| Também chamado de | Moved Temporarily |
| Definido em | RFC 9110 §15.4.3 |
| Pode ir para o cache por padrão | Só com Cache-Control ou Expires explícitos |
| Pode repetir o pedido | Siga o Location agora, mas continue usando a URL original da próxima vez |
| Cabeçalhos relevantes |
|
O que significa o 302
No HTTP/1.0 esse código se chamava Moved Temporarily; desde a RFC 2616 o nome é Found, e hoje ele está na RFC 9110, seção 15.4.3. Como a mudança é temporária, o navegador não guarda um 302 a menos que venha com Cache-Control ou Expires explícitos, e o Google o trata como sinal fraco, então a URL original continua nos resultados de busca.
Muitas ferramentas usam 302 quando você não informa o status: res.redirect(url) no Express, header("Location: ...") no PHP e Response.redirect(url) na Fetch API enviam 302. Esse padrão serve para login e desvios curtos, mas é errado para mudanças definitivas, e é um motivo frequente de um site migrado continuar com URLs antigas no Google.
O 302 também permite que o cliente troque um POST por GET no pedido seguinte, e é isso que os navegadores fazem. Depois de enviar um formulário isso não atrapalha, mas quebra chamadas de API que esperam o mesmo POST chegar ao novo endereço; para elas, use 307.
Quando usar
- Mandar o visitante deslogado para /login e depois de volta à página que ele queria.
- Desvios de curta duração: aviso de manutenção, grupo de teste A/B, página de entrada escolhida por idioma ou região a cada pedido.
- URLs sazonais ou rotativas, como /promocao, que apontam para lugares diferentes ao longo do tempo.
Causas comuns
Se você está visitando o site
- Loop de login: o site manda você para /login, a página de login nunca recebe um cookie de sessão válido (cookies bloqueados, extensão de privacidade rígida, relógio do sistema errado) e manda de volta.
- Portais de Wi-Fi de hotel, aeroporto ou café respondem qualquer requisição HTTP comum com um 302 para a página de acesso deles.
Se você administra o servidor
- O redirecionamento padrão do framework usado numa mudança de URL definitiva, fazendo os buscadores continuarem indexando o endereço antigo.
- Um cookie de sessão que é criado mas nunca volta, porque os atributos Domain, Path, Secure ou SameSite não batem com o pedido redirecionado, e o middleware de autenticação manda tudo para o login.
- Um endpoint de API respondendo POST com 302: o cliente repete a chamada como GET e sem corpo, e ela falha adiante com 405 ou erro de validação.
- Um 302 que cai numa URL que redireciona de novo, somando saltos em toda visita.
Como resolver
Se você está visitando o site
- Permita cookies para o site, apague os que já existem e faça login de novo; confira se o relógio do aparelho está certo.
- Em Wi-Fi público, abra uma página http:// simples, como http://neverssl.com, para aparecer o portal de acesso, e tente de novo.
Se você administra o servidor
- Se a mudança é definitiva, troque para 301 em páginas GET ou 308 em qualquer rota que receba outros métodos.
- Examine o Set-Cookie da resposta de login com curl -i e confira se o cookie volta no pedido redirecionado.
- Em APIs, responda 307 quando o cliente precisa repetir o mesmo pedido, ou 303 quando ele deve buscar um resultado com GET.
- Encurte as cadeias para cada 302 apontar direto para uma URL que responde 200.
Como enviar um 302
app.get('/account', (req, res) => {
if (!req.session.user) {
// res.redirect(url) alone also sends 302
return res.redirect(302, '/login?next=' + encodeURIComponent(req.originalUrl));
}
res.render('account');
});// app/account/route.ts
import { cookies } from 'next/headers';
export async function GET(request: Request) {
const session = (await cookies()).get('session');
if (!session) {
return Response.redirect(new URL('/login', request.url), 302);
}
return Response.json({ ok: true });
}mux.HandleFunc("GET /account", func(w http.ResponseWriter, r *http.Request) {
if _, err := r.Cookie("session"); err != nil {
next := url.QueryEscape(r.URL.RequestURI())
http.Redirect(w, r, "/login?next="+next, http.StatusFound) // 302
return
}
// ...render the account page
})from fastapi import FastAPI, Request
from fastapi.responses import RedirectResponse
app = FastAPI()
@app.get("/account")
def account(request: Request):
if "session" not in request.cookies:
return RedirectResponse("/login", status_code=302)
return {"ok": True}# A campaign URL that points somewhere different each season
location = /sale {
return 302 /summer-sale-2026;
}Costuma ser confundido com
- 302 vs 301
- O 301 é permanente: o navegador guarda em cache e os buscadores passam o ranqueamento para o destino. O 302 é temporário e não muda nenhum dos dois.
- 302 vs 307
- O 307 é a versão rígida do 302: o cliente precisa repetir o pedido com o mesmo método e corpo, sem trocar para GET.
- 302 vs 303
- O 303 diz explicitamente que o próximo pedido deve ser um GET para outro recurso; o 302 só tolera essa troca por motivos históricos.
Perguntas frequentes
- O redirecionamento 302 prejudica o SEO?
- Não, quando a mudança é mesmo temporária; é para isso que ele existe. O Google trata o 302 como sinal fraco e mantém a URL original nos resultados. O problema aparece quando uma mudança definitiva é feita com 302; nesse caso use 301 ou 308.
- 302 Found e 302 Moved Temporarily são a mesma coisa?
- Sim, é o mesmo código: o HTTP/1.0 (RFC 1945) o chamava de Moved Temporarily e o HTTP/1.1 renomeou para Found. A frase de status é só informativa; o cliente age pelo número.
- Por que o curl não segue o redirecionamento 302?
- O curl só segue redirecionamentos com -L (--location). Quando segue, um POST enviado com -d vira GET depois de 301, 302 ou 303; use --post302 para manter o POST, ou -X POST sabendo que ele força o método em todos os saltos.
- O 302 mantém os dados de um formulário enviado por POST?
- No navegador, não: o pedido seguinte é um GET sem corpo. Se os dados precisam chegar à nova URL, o servidor deve responder 307, que obriga o navegador a repetir o POST.
Revisado em por Arielton Oberek.