CORS explicado: preflight, headers e como resolver erros de CORS

CORS explicado

CORS explicado: preflight, headers, erros e correções | We.Inc

Como o CORS funciona: requisições simples e preflight, cada header Access-Control, regras de credenciais, os erros comuns no console e a correção no servidor para Express, Next.js e nginx.

CORS (cross-origin resource sharing) é a forma de o servidor dizer ao navegador que o JavaScript de outra origem pode ler as respostas dele. O servidor responde com Access-Control-Allow-Origin e headers relacionados. Requisições com outros métodos, headers personalizados ou corpo em JSON enviam antes um preflight OPTIONS. A correção sempre fica no servidor que você está chamando, nunca na página.

Os headers de resposta do CORS em resumo

Um erro de CORS parece indicar que o seu código está quebrado, mas em geral a requisição chegou ao servidor sem problema nenhum. O navegador apenas se recusou a entregar a resposta ao seu script. O simulador abaixo permite descrever uma requisição e a configuração do servidor e mostra se um preflight é disparado, se o navegador deixa a resposta passar e qual mensagem você veria no console.

Perguntas frequentes

Por que o Postman ou o curl funcionam quando o navegador falha?

O CORS é aplicado apenas pelos navegadores, para impedir que os scripts de um site leiam os dados de outro site usando os seus cookies. Ferramentas como o curl não executam código de página não confiável, então o ignoram. A resposta do servidor foi idêntica; só o navegador decidiu retê-la.

O que dispara uma requisição de preflight?

Qualquer método que não seja GET, HEAD ou POST, qualquer header fora dos poucos da lista segura (Accept, Accept-Language, Content-Language, Content-Type, Range), ou um Content-Type diferente de form encoding, multipart ou text/plain. Enviar application/json é o gatilho mais comum.

Dá para resolver o CORS pelo frontend?

Não. Definir headers Access-Control na sua requisição não faz nada, e mode: no-cors devolve uma resposta opaca que o seu script não consegue ler. Ou a API adiciona os headers, ou o seu próprio servidor busca os dados e os repassa.

Posso usar Access-Control-Allow-Origin: * com cookies?

Não. Quando a requisição leva credenciais, o navegador rejeita uma origem curinga e exige a origem exata mais Access-Control-Allow-Credentials: true. O mesmo vale para curingas nas listas de métodos, headers e expose headers.

Por que o meu script não consegue ler um header de resposta personalizado?

Por padrão, um script de outra origem só enxerga uma lista curta de headers de resposta seguros. Liste os demais em Access-Control-Expose-Headers, por exemplo X-Request-Id, e eles passam a ser legíveis.

Mesma origem, e por que o navegador bloqueia leituras

Requisições simples e preflights

Como ler o erro no console

Erros comuns de CORS e como corrigi-los

O texto das mensagens varia de navegador para navegador. Estes são os motivos como o Firefox os nomeia no MDN; o Chrome diz o mesmo em frases mais longas.

Motivos de CORS no console e a correção no servidor

Trechos de servidor

Express: lista de permissões com credenciais

Devolve a origem só quando ela está na lista, responde aos preflights com 204 e adiciona Vary para que os caches mantenham as origens separadas.

Route handler do Next.js

Um endpoint público e sem cookies pode usar o curinga. Exporte OPTIONS para que o preflight tenha a sua própria resposta.

nginx na frente de uma API

A flag always mantém o header também nas respostas de erro, então um 500 continua mostrando o status real em vez de um erro de CORS.

O lado do navegador: enviando cookies entre origens

credentials: "include" é o que ativa as regras de credenciais mais rígidas no servidor.

Simulador de requisições CORS

Descreva uma requisição e os headers de CORS do servidor para ver se um preflight é enviado e se o navegador deixa o seu script ler a resposta.

A requisição

A resposta do servidor

Origem da página

Origem da API

Método

Content-Type

Sem corpo

Header extra da requisição (em branco para nenhum)

Enviar cookies (credentials: include)

Access-Control-Allow-Origin

Access-Control-Allow-Methods

Access-Control-Allow-Headers

Access-Control-Allow-Credentials: true

Veredito

Mesma origem: o CORS não se aplica, a resposta pode ser lida.

Sem preflight: esta é uma requisição simples.

Preflight necessário: o navegador envia OPTIONS antes.

Motivo: o método não é GET, HEAD nem POST.

Motivo: o header {v} não está na lista segura.

Motivo: o Content-Type {v} não é um dos três tipos simples.

Permitido: o seu script pode ler a resposta.

Bloqueado. Motivo no console:

Headers que o servidor deve enviar

Comece grátis · Sem cartão de crédito

Relacionados: Guias

Produto

Para quem é

Recursos

Recursos

Empresa

Mapa do site