06 - HEAD e OPTIONS
video: https://youtu.be/... no frontmatter da nota.HEAD e OPTIONS
1. Definição e Semântica
Os métodos HTTP HEAD e OPTIONS são métodos "metadados": não alteram recursos nem solicitam o corpo de representação. Servem para inspecionar o servidor, descobrir capacidades e obter cabeçalhos sem custo de transferência do corpo. São definidos na RFC 7231 (seções 4.3.2 e 4.3.7).
Características Formais
| Atributo | HEAD | OPTIONS |
|---|---|---|
| Método | HEAD | OPTIONS |
| Seguro | Sim | Sim |
| Idempotente | Sim | Sim |
| Cacheável | Sim (apenas headers) | Não |
| Corpo na resposta | Não (apenas headers) | Opcional |
| RFC | 7231 §4.3.2 | 7231 §4.3.7 |
2. Método HEAD
HEAD é idêntico a GET, exceto que o servidor não retorna corpo na resposta. Todos os headers que seriam retornados em GET (Content-Type, Content-Length, ETag, Last-Modified, Cache-Control) devem ser idênticos.
HEAD /users/42 HTTP/1.1
Host: api.exemplo.com
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 142
ETag: "abc123"
Last-Modified: Wed, 21 Oct 2023 07:28:00 GMT
Mesmo retornando Content-Length: 142, o servidor não envia os 142 bytes — esse cabeçalho é informativo.
Casos de Uso
- Verificar existência de recurso sem baixar corpo.
- Verificar tamanho do arquivo via
Content-Lengthantes de decidir baixar. - Verificar modificação via
Last-ModifiedouETag(cache condicional). - Validar autenticação sem custo de transferência.
- Health checks: monitorar se URL responde 200 sem desperdiçar banda.
- Testar redirecionamentos: ver
Locationsem seguir redirect.
curl -I
curl -I https://www.exemplo.com/
# Equivalente a: curl --head https://www.exemplo.com/
# HTTP/2 200
# content-type: text/html
# content-length: 12540
# last-modified: Mon, 14 Oct 2024 10:00:00 GMT
# etag: "abc123"
# cache-control: max-age=3600
Respostas HEAD são cacheáveis se contiverem Cache-Control, ETag, Last-Modified — o cache pode validar entry sem precisar refazer GET.
3. Método OPTIONS
OPTIONS solicita informações sobre as opções de comunicação disponíveis para o recurso ou servidor. Pode ser enviado para URL específica (OPTIONS /users/42) ou para o servidor todo (OPTIONS *).
OPTIONS /users/42 HTTP/1.1
Host: api.exemplo.com
HTTP/1.1 200 OK
Allow: GET, HEAD, OPTIONS, PUT, PATCH, DELETE
Content-Length: 0
O header Allow lista os métodos suportados pelo recurso. Outros headers comuns: Accept-Patch (formatos de PATCH aceitos), Accept-Post (formatos de POST aceitos).
Casos de Uso
- Descoberta de capacidades da API: quais métodos um recurso suporta.
- CORS Preflight: navegador envia OPTIONS antes de certas requisições cross-origin.
- Service discovery: listar formatos aceitos (Accept-Patch, Accept-Post).
- Health check avançado: servidor responde OPTIONS sem custo de processamento de GET.
4. CORS Preflight
Navegadores implementam CORS (Cross-Origin Resource Sharing) conforme a spec Fetch. Para requisições cross-origin consideradas "não simples", o navegador envia um preflight OPTIONS antes da requisição real. São "não simples": requisições com métodos diferentes de GET/HEAD/POST, ou com headers além de Accept, Accept-Language, Content-Language, Content-Type (apenas com valores application/x-www-form-urlencoded, multipart/form-data, text/plain).
Exemplo de Preflight
OPTIONS /api/users HTTP/1.1
Origin: https://app.exemplo.com
Access-Control-Request-Method: DELETE
Access-Control-Request-Headers: Authorization, Content-Type
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://app.exemplo.com
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS
Access-Control-Allow-Headers: Authorization, Content-Type
Access-Control-Max-Age: 86400
Access-Control-Max-Age indica por quantos segundos o navegador pode cachear a resposta preflight (default 5s, máximo 24h em Chrome). Evita reenviar OPTIONS a cada requisição.
Headers CORS
| Header | Função |
|---|---|
Access-Control-Allow-Origin |
Origens autorizadas (* ou URL específica) |
Access-Control-Allow-Methods |
Métodos permitidos |
Access-Control-Allow-Headers |
Headers permitidos na requisição real |
Access-Control-Expose-Headers |
Headers que o JS pode ler na resposta |
Access-Control-Allow-Credentials |
Permite cookies/HTTP auth (true) |
Access-Control-Max-Age |
Tempo de cache do preflight |
5. Headers de Resposta Típicos
HEAD retorna os mesmos headers de um GET equivalente (Content-Type, Content-Length, ETag, Last-Modified, Vary), apenas sem o corpo. OPTIONS retorna Allow: GET, HEAD, OPTIONS, POST, opcionalmente Accept-Post e Access-Control-Allow-Origin: *.
6. Códigos de Resposta
| Status | HEAD | OPTIONS |
|---|---|---|
| 200 OK | Recurso existe, headers retornados | Recurso existe, Allow |
| 204 No Content | Recurso existe, sem payload | Capacidades descritas em headers |
| 304 Not Modified | Cache condicional via If-None-Match | Não aplicável |
| 401 Unauthorized | Recurso protegido, falta auth | Preflight com credenciais sem auth |
| 403 Forbidden | Sem permissão | Origin não autorizada em CORS |
| 404 Not Found | Recurso não existe | Recurso não existe |
| 405 Method Not Allowed | Recurso não suporta HEAD | Recurso não suporta OPTIONS |
| 501 Not Implemented | Servidor não implementa HEAD | Servidor não implementa OPTIONS |
7. Exemplos Práticos
# Verificar tamanho de download
curl -sI https://download.exemplo.com/arquivo.zip | head -10
# HTTP/2 200; content-length: 10485760; accept-ranges: bytes
# Cache validation (HEAD com If-None-Match)
curl -I -H 'If-None-Match: "v1"' https://api.exemplo.com/users/42
# HTTP/1.1 304 Not Modified se cache ainda válido
# Descobrir métodos suportados
curl -X OPTIONS https://api.exemplo.com/users/42 -i
# Verifica header Allow
# CORS preflight
curl -X OPTIONS https://api.exemplo.com/users \
-H "Origin: https://app.exemplo.com" \
-H "Access-Control-Request-Method: DELETE" \
-H "Access-Control-Request-Headers: Authorization" -i
# Health check com HEAD
while true; do
STATUS=$(curl -sI -o /dev/null -w "%{http_code}" https://api.exemplo.com/health)
[ "$STATUS" != "200" ] && echo "$(date) - Falha: $STATUS"
sleep 5
done
8. Boas Práticas
- Implementar HEAD para todo recurso GET: Mesma lógica de headers, omitindo apenas o corpo. Facilita cache, monitoramento e validação.
- Responder OPTIONS em todo endpoint: Sempre habilitado, mesmo que apenas retorne
Allow. Não exigir autenticação em OPTIONS (caso contrário, preflight CORS falha). - Headers CORS consistentes: Configurar CORS no nível do servidor/proxy, não por endpoint. Inconsistências causam bugs difíceis de diagnosticar.
- Cache preflight: Usar
Access-Control-Max-Age: 86400para reduzir tráfego de preflight. Browsers cacheiam por até 24h.
9. Erros Comuns
| Erro | Causa | Correção |
|---|---|---|
| HEAD retorna body | Implementação errada | Não enviar corpo no HEAD |
| HEAD omite Content-Length | Header inconsistente | Replicar headers de GET |
| OPTIONS exige auth | Bloqueia preflight CORS | Isentar OPTIONS de autenticação |
| Allow incorreto | Lista métodos não implementados | Listar apenas métodos realmente suportados |
| 405 em OPTIONS | Servidor não implementa OPTIONS | Habilitar OPTIONS no framework |
10. Resumo Técnico
| Atributo | HEAD | OPTIONS |
|---|---|---|
| RFC | 7231 §4.3.2 | 7231 §4.3.7 |
| Seguro | Sim | Sim |
| Idempotente | Sim | Sim |
| Cacheável | Sim (headers) | Não |
| Corpo resposta | Não | Opcional |
| Header chave | Content-Length, ETag | Allow, Accept-* |
| Uso típico | Cache, health check | CORS preflight, descoberta |
11. Conclusão
HEAD e OPTIONS são métodos frequentemente subestimados, mas essenciais para o funcionamento correto da web moderna. HEAD permite verificações de cache e health checks sem custo de banda, enquanto OPTIONS é indispensável para o mecanismo de CORS, habilitando aplicações single-page (SPA) a consumirem APIs cross-origin de forma segura. A implementação correta de ambos — com consistência de headers em HEAD e respostas CORS adequadas em OPTIONS — é sinal de maturidade em uma API REST. Servidores como Nginx, Apache e frameworks modernos (Express, Django, FastAPI) suportam ambos nativamente, mas a configuração correta de CORS ainda é uma fonte comum de bugs em aplicações web.