DWEB 01.7 Códigos de Status HTTP (2xx, 3xx, 4xx, 5xx) e Cabeçalhos (Request e Response)
Imagine que você liga para um restaurante para pedir uma reserva. Em vez de só dizer “feito” ou “não feito”, o atendente responde com uma frase mais útil: “reserva confirmada para 20h”, “infelizmente está lotado”, “favor ligar de novo em cinco minutos”, “houve um problema no nosso sistema”. Cada uma dessas respostas dá uma pista clara sobre o que aconteceu — e, mais importante, sobre o que você deve fazer em seguida. O HTTP funciona com essa mesma lógica de respostas estruturadas: a cada requisição, o servidor responde com um código de status que classifica o resultado em uma de cinco famílias. Acompanhando esse código, viaja um conjunto de cabeçalhos com metadados sobre a comunicação. Saber ler ambos — códigos e cabeçalhos — é o que transforma um desenvolvedor curioso em um desenvolvedor produtivo na hora de depurar problemas.
Códigos de status: as cinco famílias
Todo código de status HTTP é um número de três dígitos. O primeiro dígito identifica a família da resposta. Cada família tem um sentido geral, e dentro dela existem códigos específicos. As cinco famílias são:
| Família | Faixa | Sentido geral |
|---|---|---|
| 1xx | Informacional | “Em andamento, aguarde” |
| 2xx | Sucesso | “Deu certo” |
| 3xx | Redirecionamento | “O que você quer está em outro lugar” |
| 4xx | Erro do cliente | “Você fez algo errado no pedido” |
| 5xx | Erro do servidor | “Eu (servidor) tenho um problema interno” |
Essa classificação é uma das peças mais elegantes do HTTP. Com apenas o primeiro dígito do código de status, você já tem uma ideia razoável do que aconteceu. Vamos aprofundar nas famílias que mais aparecem no dia a dia.
1xx — Informacional
A família 1xx é raríssima no dia a dia do front-end. Indica que a requisição foi recebida e o processamento continua. O caso mais conhecido é o 100 Continue, usado em uploads grandes, quando o cliente pergunta ao servidor “posso continuar enviando?”. Em geral, você não vai ver códigos 1xx aparecerem nas suas ferramentas comuns.
2xx — Sucesso
Aqui mora a maior parte das respostas felizes. Os códigos mais importantes:
- 200 OK — a requisição deu certo. É o código mais comum da web. Toda página que carrega bem, em essência, vem com um 200.
- 201 Created — usado especialmente em respostas a
POSTbem-sucedidos. Indica que um novo recurso foi criado. Costuma vir acompanhado de um cabeçalhoLocationcom a URL do recurso recém-criado. - 204 No Content — sucesso, mas sem corpo de resposta. Comum em respostas a
DELETEou aPUT/PATCHquando o servidor não devolve dados.
3xx — Redirecionamento
Os códigos 3xx dizem ao cliente: “vá para outro endereço”. Os mais comuns:
- 301 Moved Permanently — o recurso mudou de endereço definitivamente. Navegadores e mecanismos de busca atualizam suas referências. Muito usado quando um site reformula sua estrutura de URLs ou troca de domínio.
- 302 Found (também chamado historicamente de “Moved Temporarily”) — redirecionamento temporário. O navegador segue para o novo endereço naquela vez, mas mantém o original em memória para próximos acessos.
- 304 Not Modified — o recurso não mudou desde a última vez que o cliente o pegou. Esse código é usado em conjunto com mecanismos de cache: o cliente avisa ao servidor “tenho esta versão do recurso, ainda vale?”, e o servidor responde
304se nada mudou. Resultado: o cliente usa a versão local, sem precisar baixar de novo. Economia de banda.
Em todos os 3xx, a resposta vem com um cabeçalho Location indicando para onde ir.
4xx — Erro do cliente
A família 4xx é uma das mais úteis para o trabalho do desenvolvedor front-end, porque indica que alguma coisa no pedido está errada — e geralmente é algo que o cliente (ou seu código) pode corrigir. Os códigos mais comuns:
- 400 Bad Request — a requisição está malformada. O servidor não consegue interpretá-la.
- 401 Unauthorized — falta autenticação. Em palavras simples: “não sei quem você é, faça login”. Apesar do nome (que tem “unauthorized”), é mais sobre identidade do que sobre permissão.
- 403 Forbidden — o cliente está autenticado, mas não tem permissão para esse recurso. “Eu sei quem você é, mas você não pode entrar aqui.”
- 404 Not Found — o recurso pedido não existe no servidor. É, talvez, o código de erro mais conhecido do mundo (até em camisetas e memes).
- 405 Method Not Allowed — o método usado não é aceito para esse recurso. Por exemplo: tentar dar
POSTem uma URL que só aceitaGET. - 409 Conflict — a requisição entra em conflito com o estado atual do recurso. Comum em criações duplicadas (criar um usuário com um e-mail que já existe, por exemplo).
- 422 Unprocessable Entity — a requisição está bem formada, mas os dados não passam em alguma validação semântica (campo obrigatório em branco, valor fora de faixa, etc.).
- 429 Too Many Requests — o cliente fez requisições demais em um curto período. Servidores usam isso para se proteger de abuso e de robôs.
Conhecer essas distinções fines (especialmente entre 401 e 403, entre 400 e 422) ajuda muito a interpretar logs e a construir mensagens claras para o usuário final.
5xx — Erro do servidor
A família 5xx indica que algo está errado no servidor. O cliente fez tudo certo, em princípio, mas o servidor falhou. Os principais:
- 500 Internal Server Error — erro genérico do servidor. Frequentemente significa que algum código no back-end “explodiu” sem tratamento.
- 502 Bad Gateway — o servidor estava agindo como intermediário e recebeu uma resposta inválida de outro servidor.
- 503 Service Unavailable — o servidor está temporariamente indisponível (manutenção, sobrecarga). Voltar a tentar mais tarde costuma resolver.
- 504 Gateway Timeout — o servidor intermediário esperou demais por uma resposta e desistiu.
Quando você vê um 5xx, o problema raramente é do front-end. O ideal é avisar a equipe de back-end ou olhar logs do servidor. Como desenvolvedor front-end, sua responsabilidade nesses casos é tratar bem o erro na interface: mostrar uma mensagem clara ao usuário, sugerir tentar de novo, e não fazer a aplicação travar.
Cabeçalhos: metadados das requisições e respostas
Além do método e do status, requisições e respostas HTTP carregam um conjunto de cabeçalhos — pares “chave: valor” que dão informações adicionais sobre a comunicação. Cabeçalhos não fazem parte do corpo da mensagem; são metadados, como um envelope que envolve a carta.
Os cabeçalhos se dividem em dois grupos principais: os de requisição (request headers, enviados pelo cliente) e os de resposta (response headers, enviados pelo servidor). Vamos olhar os mais comuns de cada lado.
Cabeçalhos de requisição (request)
São cabeçalhos enviados pelo navegador (ou outro cliente) ao fazer um pedido. Os principais:
- Host — o nome do domínio sendo acessado. Importante quando um mesmo servidor hospeda vários sites.
- User-Agent — identifica o navegador e o sistema operacional do cliente. É por aí que servidores conseguem detectar se você está em Windows, Mac, celular Android, etc.
- Accept — quais formatos de resposta o cliente aceita. Por exemplo,
Accept: text/htmlpara páginas HTML,Accept: application/jsonpara APIs que retornam JSON. - Accept-Language — quais idiomas o cliente prefere (por exemplo,
pt-BR, pt;q=0.9, en;q=0.8). Sites multilíngues podem usar isso para escolher o idioma da página automaticamente. - Authorization — credenciais de autenticação. Em APIs modernas, costuma ser algo como
Authorization: Bearer <token>. - Cookie — cookies armazenados pelo navegador para esse site. Carregam, por exemplo, identificação de sessão, preferências e itens de carrinho.
- Content-Type — quando a requisição tem corpo (POST, PUT, PATCH), indica o formato do corpo. Os mais comuns são
application/jsonemultipart/form-data. - Referer — qual a URL anterior que levou o cliente até aqui (sim, o cabeçalho é escrito errado historicamente, com um “r” a menos; vale como nome próprio).
Cabeçalhos de resposta (response)
São cabeçalhos enviados pelo servidor com a resposta. Os principais:
- Content-Type — formato do corpo da resposta (por exemplo,
text/html; charset=UTF-8para uma página HTML em UTF-8, ouapplication/jsonpara uma resposta de API). - Content-Length — tamanho do corpo, em bytes.
- Set-Cookie — instrução para o navegador armazenar um cookie.
- Cache-Control — instruções de cache: por quanto tempo a resposta pode ficar guardada, se pode ser compartilhada, etc.
- Location — usado em respostas 3xx (redirecionamento) ou 201 (criado): indica a URL de destino ou do novo recurso.
- ETag — um identificador único para a versão atual do recurso. Usado em conjunto com cache.
- Access-Control-Allow-Origin — usado em respostas a requisições de outra origem; faz parte do mecanismo de CORS.
Cabeçalhos podem parecer detalhe técnico, mas eles controlam comportamentos essenciais: como o navegador interpreta o conteúdo, se cacheia, se autoriza chamadas, em qual idioma exibe a página. Saber lê-los é metade do trabalho de depuração em front-end.
Caso ilustrativo: investigando uma página lenta
Imagine que uma desenvolvedora foi chamada para resolver um problema relatado por uma loja online: “a página de listagem de produtos está demorando muito para carregar, principalmente para usuários novos”. Ela abre a página, ativa as ferramentas de inspeção do navegador, recarrega — e olha o que aparece na aba de rede:
- A requisição principal
GET /produtosvolta com status200 OK. Tempo: 320 ms. OK. - Mas as imagens de cada produto vêm com
200 OK, cada uma demorando entre 800 ms e 2 segundos. Isso já é estranho. - Observando os cabeçalhos de uma das imagens, ela vê:
Cache-Control: no-store. Aí está o problema: cada imagem é baixada de novo a cada acesso, sem cache. Para o primeiro acesso de um usuário, tudo bem. Para o segundo, terceiro, quarto, é um desperdício.
Com essa informação, a desenvolvedora pode pedir à equipe de back-end que ajuste o Cache-Control das imagens para algo como Cache-Control: public, max-age=86400 (cache de um dia). O efeito é imediato: usuários que voltam ao site veem a página carregar quase instantaneamente. Cinco segundos olhando um cabeçalho valeram horas que teriam sido gastas em otimizações erradas.
Caso ilustrativo, criado para fins didáticos.
Momento de aplicação prática
Abra qualquer site no seu navegador, ative as ferramentas de desenvolvedor (a tecla F12 em Windows e Linux, ou Cmd+Option+I em Mac) e clique na aba Network (em alguns navegadores em português, “Rede”). Recarregue a página com F5.
Você verá, em tempo real, todas as requisições que o navegador faz para carregar aquela página: o HTML principal, as imagens, os arquivos CSS, os arquivos JavaScript, eventuais chamadas de API. Clicando em qualquer uma delas, você verá:
- O método usado.
- O status retornado.
- Os cabeçalhos de requisição e de resposta.
- O corpo da resposta.
- Quanto tempo levou cada parte da requisição.
Sugiro o seguinte exercício: identifique, em uma página, uma requisição com status 200, uma com status 3xx (se houver) e tente forçar uma com status 404 digitando, na barra de endereço, uma URL inexistente do mesmo site. Faça isso até se sentir confortável com a aba Network. Ela vai ser sua companheira diária.
Voltaremos a esse uso do DevTools no próximo tópico, com mais profundidade.
Armadilha comum
Iniciantes às vezes interpretam qualquer erro 4xx como “bug no front-end” e qualquer erro 5xx como “bug no servidor”. A regra geral é boa, mas tem exceções importantes:
- Um
404pode significar que o front-end chamou a URL errada — mas também pode significar que o servidor está mal configurado, ou que o recurso foi removido. - Um
401muitas vezes indica que o front-end deixou de enviar o token de autenticação corretamente — e isso é um bug do front-end, sim. - Um
500em desenvolvimento pode estar acontecendo porque o front-end enviou dados em formato inesperado, e o back-end não tratou o erro. Em casos assim, embora o status seja 5xx, a causa raiz pode estar no front-end.
A lição é: status indica origem provável, não certeza. Investigue antes de apontar o dedo.
O que vem a seguir
Você já entende, em linhas gerais, o que acontece em uma requisição HTTP. Falta agora abrir a janela para o local onde tudo isso acontece para você, na prática: o navegador. Como ele renderiza uma página, quais são seus motores internos, e como usar a fundo as ferramentas de desenvolvedor — assunto do próximo tópico, e talvez o mais útil desta aula no curtíssimo prazo.