03 - 3xx - Redirecionamento (300)
video: https://youtu.be/... no frontmatter da nota.3xx - Redirecionamento
1. Definição e Características
A classe de status HTTP 3xx Redirection (RFC 7231 §6.4, obsoleta por RFC 9110) indica ao cliente que precisa executar uma ação adicional para completar a requisição — tipicamente, acessar uma URL diferente informada no header Location. São usadas para mudanças de URL, balanceamento geográfico, A/B testing, cache condicional e reescrita de fluxo.
- Faixa numérica: 300 a 399
- Header chave:
Location(URL de destino) - Cacheável: Sim, conforme
Cache-Controle natureza (permanente vs temporário)
Tipos de Redirecionamento
| Tipo | Característica | Códigos |
|---|---|---|
| Permanente | Cliente e caches lembram para sempre | 301, 308 |
| Temporário | Cliente reconsulta URL original a cada requisição | 302, 303, 307 |
| Cache condicional | Recurso não modificado, use cache | 304 |
| Outros | Escolha múltipla, proxy | 300, 305 |
Códigos 3xx Padronizados
| Código | Nome | RFC |
|---|---|---|
| 300 | Multiple Choices | 7231 §6.4.1 |
| 301 | Moved Permanently | 7231 §6.4.2 |
| 302 | Found | 7231 §6.4.3 |
| 303 | See Other | 7231 §6.4.4 |
| 304 | Not Modified | 7232 §4.1 |
| 305 | Use Proxy (obsoleto) | 7231 §6.4.5 |
| 306 | (reservado, obsoleto) | Histórico |
| 307 | Temporary Redirect | 7231 §6.4.7 |
| 308 | Permanent Redirect | 7538 |
2. 301 Moved Permanently
Indica que o recurso foi movido permanentemente para a URL informada em Location. Buscadores atualizam o índice para a nova URL. Browsers e caches armazenam o redirecionamento, evitando nova requisição à URL original.
HTTP/1.1 301 Moved Permanently
Location: https://www.exemplo.com/nova-pagina
Cache-Control: max-age=86400
Impacto SEO: Google/Bing transferem o "link juice" da URL antiga para a nova (atualização do índice pode levar dias/semanas). Cache do navegador evita futuras requisições à URL antiga. Em 301, browsers tradicionalmente mudavam POST para GET na nova URL (comportamento não padronizado), o que motivou a criação do 308.
Casos de uso: migração de domínio (meusite.com → www.meusite.com); mudança de protocolo (http:// → https://); reestruturação de URLs (/blog/post-1 → /articles/post-1); aposentadoria de páginas antigas.
3. 302 Found
Indica redirecionamento temporário. O recurso está momentaneamente em outra URL, mas o cliente deve continuar usando a URL original em requisições futuras. Caches não devem armazenar o redirecionamento por padrão.
HTTP/1.1 302 Found
Location: https://maintenance.exemplo.com/
Cache-Control: no-store
302 foi o código original para redirecionamento temporário. Por razões históricas, browsers mudavam POST para GET na nova URL — comportamento que quebrou várias aplicações. Para resolver ambiguidade, foram criados 303 e 307.
Casos de uso: manutenção temporária; A/B testing; login redirects.
Diferença 301 vs 302
| Critério | 301 | 302 |
|---|---|---|
| Permanência | Permanente | Temporário |
| Cache navegador | Sim (lembrado) | Não (reconsulta) |
| SEO | Transfere autoridade | Não transfere |
| Uso | Migração | A/B testing, manutenção |
4. 303 See Other
Indica que a resposta à requisição pode ser obtida em outra URL via método GET. É o redirecionamento correto para o padrão "POST → GET redirect" (Post/Redirect/Get), usado para evitar reenvio de formulário em F5.
POST /login HTTP/1.1
HTTP/1.1 303 See Other
Location: /dashboard
Browser faz GET /dashboard. Se usuário apertar F5, refaz apenas o GET /dashboard, não o POST /login (evita reenviar credenciais).
Casos de uso: após submeter formulário, redirecionar para página de sucesso; após POST que cria recurso, redirecionar para GET do recurso criado; forçar método GET independente do método original.
5. 304 Not Modified
Indica que o recurso não foi modificado desde a última requisição do cliente. Não há corpo na resposta. O cliente deve usar a versão em cache.
GET /styles.css HTTP/1.1
If-None-Match: "abc123"
If-Modified-Since: Wed, 21 Oct 2023 07:28:00 GMT
HTTP/1.1 304 Not Modified
ETag: "abc123"
Cache-Control: max-age=3600
Cliente envia If-None-Match com a ETag recebida anteriormente, ou If-Modified-Since com a data de Last-Modified. Se o servidor verificar que o recurso não mudou, responde 304 (sem corpo). Caso contrário, responde 200 OK com o recurso completo.
Benefícios: economia de banda (corpo não é transferido); redução de latência (resposta menor); menor carga no servidor (não gera processamento de geração do recurso).
Headers envolvidos: ETag (versão do recurso), Last-Modified (data de modificação), If-None-Match (envia ETag do cache do cliente), If-Modified-Since (envia data do cache), If-Unmodified-Since (concorrência — rejeita se modificado), If-Range (range request condicional).
6. 307 Temporary Redirect
Redirecionamento temporário que preserva o método HTTP original. Se a requisição original era POST, o cliente deve refazer POST na nova URL (não GET).
POST /api/v1/users HTTP/1.1
{"name":"Alice"}
HTTP/1.1 307 Temporary Redirect
Location: /api/v2/users
Cliente envia POST /api/v2/users com o mesmo corpo.
Diferença 302 vs 307
| Critério | 302 | 307 |
|---|---|---|
| Permanência | Temporário | Temporário |
| Preserva método | Não (POST → GET) | Sim (POST → POST) |
| Padrão | Histórico | Moderno |
7. 308 Permanent Redirect
Redirecionamento permanente que preserva o método HTTP. Equivale ao 301, mas não altera o método da requisição.
PUT /api/v1/users/42 HTTP/1.1
{"name":"Alice"}
HTTP/1.1 308 Permanent Redirect
Location: /api/v2/users/42
Cliente envia PUT /api/v2/users/42 com o mesmo corpo.
Casos de uso: migração de versão de API (/v1/ → /v2/) preservando método; mudança permanente de endpoint que recebe POST/PUT/DELETE.
8. Comparativo Completo
| Código | Permanente? | Método preservado? | Cache? |
|---|---|---|---|
| 301 | Sim | Não (POST→GET) | Sim |
| 302 | Não | Não (POST→GET) | Não |
| 303 | Não | Força GET | Não |
| 304 | - | - | (validação de cache) |
| 307 | Não | Sim | Não |
| 308 | Sim | Sim | Sim |
9. Exemplos Práticos
# curl seguindo redirects (-L)
curl -L https://exemplo.com/pagina-antiga
# curl mostrando redirect sem seguir (-v): HTTP/1.1 301 Moved Permanently
# Cache condicional (304): curl -I -H 'If-None-Match: "abc123"' https://api.exemplo.com/styles.css
Nginx — Redirect
server { listen 80; server_name exemplo.com;
return 301 https://www.exemplo.com$request_uri; }
location /old-api/ { return 307 https://api.exemplo.com/v2$request_uri; }
10. Boas Práticas
- 301 para mudanças permanentes: migração de domínio, HTTPS, reestruturação de URL. SEO beneficia-se do cache e da transferência de autoridade.
- Evitar 302 para mudanças permanentes: Google pode não transferir SEO authority em 302; pode tratar como "temporário" indefinidamente.
- 307/308 em APIs com métodos não-GET: um POST não deve virar GET em redirect — usar 307 (temporário) ou 308 (permanente).
- Limitar cadeia de redirects: cadeias longas (A → B → C → D) aumentam latência e podem quebrar clients. Manter 1-2 hops; browsers limitam a ~20 redirects.
- Cache-Control em redirects permanentes:
Cache-Control: max-age=86400permite caches e browsers armazenarem o redirect por 24h, evitando reconsulta. - Manter parâmetros de query: ao redirecionar, preservar query string se aplicável (
return 301 https://novo.exemplo.com$request_uri).
11. Erros Comuns
| Erro | Causa | Correção |
|---|---|---|
| Loop infinito de redirect | A → B → A | Verificar lógica de redirect |
| 302 em mudança permanente | Perda de SEO | Usar 301 |
| 301 em teste A/B | Browser cacheia, não permite alternar | Usar 302 |
| Redirect perde método | POST vira GET | Usar 307 ou 308 |
| Redirect não preserva query | Query string descartada | Usar $request_uri ou $args |
12. Resumo Técnico
| Atributo | Valor |
|---|---|
| Faixa | 300-399; Header chave: Location |
| Cacheável | Sim (301, 308); Condicional (304) |
| Codigos principais | 301, 302, 303, 304, 307, 308 |
| RFC | 7231 §6.4; 7232 §4.1 (304); 7538 (308) |
13. Conclusão
A classe 3xx é fundamental para a web: redirecionamentos, cache condicional e padrões como Post/Redirect/Get. A escolha entre 301, 302, 303, 307 e 308 tem impacto em SEO, cache de browsers e preservação de métodos.