Código de status HTTP · Redirecionamento (3xx)
301 Moved Permanently
O redirecionamento 301 (Moved Permanently) significa que o recurso agora mora na URL do cabeçalho Location e todos os próximos acessos devem ir para lá. É o jeito padrão de mudar uma página de endereço de vez, como ao trocar o slug, migrar de HTTP para HTTPS ou unificar o domínio com e sem www.
| Classe | 3xx, Redirecionamento |
|---|---|
| Definido em | RFC 9110 §15.4.2 |
| Pode ir para o cache por padrão | Sim, de forma heurística; sem Cache-Control, navegadores costumam guardá-lo sem prazo |
| Pode repetir o pedido | Siga o Location agora e mande os próximos pedidos para a nova URL |
| Cabeçalhos relevantes |
|
O que significa o 301
A RFC 9110, seção 15.4.2, diz que o 301 indica que o recurso ganhou uma nova URI permanente e que as referências futuras devem usá-la. O navegador segue o Location na hora e, como o 301 pode ser guardado em cache de forma heurística, Chrome e Firefox costumam lembrar dele sem prazo de validade. O visitante pode continuar sendo mandado para a URL nova pelo próprio cache muito depois de você apagar a regra no servidor.
A especificação também mantém uma herança antiga: o cliente pode transformar um POST em GET ao seguir um 301, e todos os navegadores principais fazem isso, descartando o corpo da requisição. Para formulários e endpoints de API que recebem POST, PUT ou DELETE, use o 308 Permanent Redirect, que mantém o método e o corpo.
Na documentação do Google, o 301 é um sinal forte de que o destino deve ser a URL canônica, então a URL nova substitui a antiga nos resultados de busca. Cadeias de redirecionamento continuam custando caro: os rastreadores do Google desistem depois de 10 saltos, e cada salto extra é mais uma ida e volta para quem está numa conexão lenta.
Quando usar
- Uma página, produto ou artigo que mudou de URL definitivamente.
- Forçar um único esquema e host canônicos: http para https, www para o domínio sem www ou o contrário.
- Juntar URLs antigas depois de uma migração de site ou de uma mudança na estrutura de URLs do CMS.
- Use para tráfego GET e HEAD; endpoints que recebem POST devem ganhar um 308.
Causas comuns
Se você está visitando o site
- O navegador mostra "muitos redirecionamentos" (ERR_TOO_MANY_REDIRECTS) porque o site fica pulando entre http e https, ou entre www e sem www, em loop.
- Um 301 antigo guardado no cache continua mandando você para um endereço que o site não usa mais.
Se você administra o servidor
- Redirecionamento para HTTPS atrás de proxy ou CDN: a aplicação recebe HTTP puro vindo do proxy (o modo SSL Flexible da Cloudflare é o caso clássico), redireciona para https, e o proxy pede de novo por HTTP, para sempre.
- Duas camadas discordam sobre o host canônico: o nginx manda o www para o domínio sem www e o CMS (a opção siteurl do WordPress, por exemplo) manda de volta para o www.
- Cadeias que sobraram de várias migrações, como /a para /b para /c para https://www.exemplo.com/c, cada salto somando latência.
- Um 301 usado para uma mudança que era temporária, agora guardado nos navegadores, o que impede reaproveitar a URL antiga com facilidade.
- Requisições POST para um endpoint que mudou de lugar perdendo o corpo porque o cliente reenvia como GET.
Como resolver
Se você está visitando o site
- Apague os cookies e os arquivos em cache do site (no Chrome: Configurações, Privacidade e segurança, Excluir dados de navegação, imagens e arquivos em cache); isso também remove 301 guardados.
- Abra a página numa janela anônima: se carregar ali, o problema é um redirecionamento ou cookie antigo no seu perfil normal.
Se você administra o servidor
- Rastreie cada salto com curl -sIL https://exemplo.com/pagina-antiga e aponte cada URL antiga direto para o destino final.
- Atrás de proxy, decida o redirecionamento para https pelo X-Forwarded-Proto (ou mude a Cloudflare para SSL Full ou Full (strict)) em vez do esquema que a aplicação enxerga na conexão.
- Aplique o host e o esquema canônicos em uma única camada, no servidor web ou na aplicação, nunca nas duas.
- Enquanto testa uma regra nova, use 302 ou adicione Cache-Control: max-age=3600 ao 301, para um erro não ficar morando no navegador dos visitantes.
- Troque para 308 nos endpoints redirecionados que recebem POST, PUT, PATCH ou DELETE.
Como enviar um 301
app.get('/blog/:slug', (req, res) => {
res.redirect(301, `/articles/${req.params.slug}`);
});// app/blog/[slug]/route.ts
export async function GET(
request: Request,
{ params }: { params: Promise<{ slug: string }> }
) {
const { slug } = await params;
// Response.redirect needs an absolute URL
return Response.redirect(new URL(`/articles/${slug}`, request.url), 301);
}
// next.config.js: permanent: true sends 308; ask for 301 explicitly
// redirects: async () => [
// { source: '/blog/:slug', destination: '/articles/:slug', statusCode: 301 }
// ]mux.HandleFunc("GET /blog/{slug}", func(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/articles/"+r.PathValue("slug"), http.StatusMovedPermanently) // 301
})from fastapi import FastAPI
from fastapi.responses import RedirectResponse
app = FastAPI()
@app.get("/blog/{slug}")
def old_blog_post(slug: str):
# RedirectResponse defaults to 307; say 301 explicitly
return RedirectResponse(f"/articles/{slug}", status_code=301)# http:// and www. both go to https://example.com, in one hop
server {
listen 80;
server_name example.com www.example.com;
return 301 https://example.com$request_uri;
}
# A single moved page
location = /old-pricing {
return 301 /pricing;
}Costuma ser confundido com
- 301 vs 308
- Os dois são permanentes e o Google trata igual; o 308 proíbe trocar POST por GET, enquanto o 301 permite e os navegadores trocam.
- 301 vs 302
- O 302 é temporário: o navegador não guarda em cache por padrão e os buscadores mantêm a URL original no índice.
- 301 vs 410
- Use 410 Gone quando não existe página substituta; um 301 para uma página sem relação, como a home, é tratado pelo Google como soft 404.
Perguntas frequentes
- O redirecionamento 301 passa a autoridade de SEO para a nova URL?
- O Google descreve o 301 como um sinal forte de que o destino deve ser a URL canônica, então a página nova assume o lugar da antiga nos resultados, junto com os sinais dela. Mantenha o redirecionamento enquanto a URL antiga ainda receber links ou visitas, de preferência por um ano ou mais.
- Por quanto tempo o navegador guarda um 301 em cache?
- Sem Cache-Control ou Expires, o 301 pode ficar em cache sem limite definido, e na prática Chrome e Firefox o mantêm até o cache ser limpo. Se existe chance de desfazer o redirecionamento, envie Cache-Control com um max-age que você aceite esperar.
- Devo usar 301 ou 308?
- Para páginas comuns acessadas com GET, os dois funcionam igual e o Google trata igual. Use 308 quando a URL redirecionada recebe POST, PUT ou DELETE, porque o 301 deixa o cliente transformar esses pedidos em GET e perder o corpo.
- Como resolver ERR_TOO_MANY_REDIRECTS depois de criar um 301?
- Rode curl -sIL na URL para enxergar o loop. Quase sempre são duas regras se desfazendo: um redirecionamento para https atrás de um proxy que fala com a origem por HTTP, ou regras de host no servidor e no CMS apontando em direções opostas.
Revisado em por Arielton Oberek.