---
term: 'CORS (Cross-Origin Resource Sharing)'
seoTitle: 'O que é CORS? Erros, Preflight e Correções'
headline: 'O que é CORS (Cross-Origin Resource Sharing)?'
slug: cors
category: api-realtime
shortDefinition: 'CORS é um mecanismo do navegador que permite ao servidor declarar quais outras origens podem chamá-lo, relaxando de propósito a política de same-origin.'
relatedTerms:
  - api-key-security
  - api-gateway-architecture
  - cross-site-scripting-xss-prevention
contrastsWith:
  - cross-site-scripting-xss-prevention
faq:
  - question: 'O que é CORS em termos simples?'
    answer: 'O sistema de permissão do navegador para chamadas de API entre sites. Por padrão, scripts em uma origin não conseguem ler respostas de outra — a política de same-origin. CORS é como um servidor faz o opt-in: headers de resposta declarando quais origens, métodos e headers ele aceita. O navegador aplica; o servidor declara; seu código de frontend é só o mensageiro.'
  - question: 'O que é uma origin, exatamente?'
    answer: 'A tripla esquema, host e porta. https://app.example.com e https://api.example.com são origens diferentes (o host difere); as versões http e https de um mesmo site também (o esquema difere), assim como :3000 vs :8080 no desenvolvimento (a porta difere). Toda decisão de CORS compara essas três partes — nada mais na URL importa.'
  - question: 'Como resolver erro de CORS?'
    answer: 'O navegador chamou uma origin diferente e a resposta não trouxe um header Access-Control-Allow-Origin combinando com a sua — então o navegador impediu seu script de lê-la. A requisição muitas vezes chegou bem ao servidor; o bloqueio é client-side, na leitura. Por isso a correção é sempre configuração de servidor — adicionar sua origin à lista permitida — e nunca código de frontend.'
  - question: 'O que é uma requisição de preflight?'
    answer: 'A checagem prévia de permissão do navegador para requisições não simples: antes de enviar um PUT, um DELETE ou qualquer coisa com headers customizados, como um token de autorização, ele envia uma requisição OPTIONS perguntando "posso?". Os headers do servidor respondem quais métodos, headers e origens são permitidos; só então a requisição real é enviada. Preflights são cacheáveis via Access-Control-Max-Age.'
  - question: 'Por que a requisição funciona no curl mas falha no navegador?'
    answer: 'Porque CORS é aplicação pelo navegador, não rejeição pelo servidor. Ferramentas como o curl e apps mobile nativos não têm política de same-origin, então leem a resposta tranquilamente. O navegador aplica a política em nome do usuário — a diferença que você está vendo é o ponto de aplicação, e é também a prova de que CORS não é controle de acesso.'
  - question: 'Access-Control-Allow-Origin: * é seguro?'
    answer: 'Para APIs genuinamente públicas e sem credenciais, sim. O wildcard é proibido no modo com credenciais — navegadores recusam cookies contra ele por design — e refletir origens arbitrárias enquanto se permitem credenciais é a má configuração clássica que transforma o CORS de escudo em buraco. APIs privadas listam origens explicitamente.'
  - question: 'Posso simplesmente desabilitar o CORS para resolver o erro?'
    answer: 'Só no sentido em que remover o alarme de incêndio resolve o incêndio. Flags de navegador e proxies permissivos mascaram o sintoma na sua máquina enquanto entregam a quebra para todos os usuários. A correção certa leva minutos: configure o servidor (ou o dashboard da plataforma) para permitir as origens que devem chamá-lo.'
  - question: 'Qual a diferença entre CORS, CSRF e CSP?'
    answer: 'Três trabalhos diferentes. CORS governa quais origens podem ler respostas de um servidor. CSRF é um ataque — pegar carona nos cookies de um usuário para forjar requisições — combatido com tokens e cookies SameSite, não com CORS. CSP é a política da própria página restringindo o que ela pode carregar e executar, a ferramenta anti-XSS. Siglas vizinhas, mecanismos ortogonais.'
codeLanguages: [javascript, dart, swift, kotlin]
externalAuthorities:
  - name: 'CORS — MDN Web Docs'
    url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS'
  - name: 'Fetch Standard — CORS protocol (WHATWG)'
    url: 'https://fetch.spec.whatwg.org/#http-cors-protocol'
  - name: 'Same-origin policy — MDN Web Docs'
    url: 'https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy'
  - name: 'Back4app documentation'
    url: 'https://www.back4app.com/docs'
  - name: 'Cross-origin resource sharing — Wikipedia'
    url: 'https://en.wikipedia.org/wiki/Cross-origin_resource_sharing'
cta:
  title: 'Cross-origin que simplesmente funciona'
  text: 'As APIs do Back4app respondem preflights e enviam os headers de CORS corretos de fábrica — seu app web chama o backend de qualquer origem que você permitir, enquanto apps nativos pulam a cerimônia por completo. Nenhuma gambiarra de proxy, nunca.'
  linkText: 'Comece grátis'
  linkUrl: 'https://www.back4app.com/signup'
author: 'Back4app Engineering'
publishedDate: '2026-08-21'
translationKey: cors-cross-origin-resource-sharing
---

**CORS é um mecanismo do navegador que permite ao servidor declarar quais outras origens podem chamá-lo, relaxando de propósito a política de same-origin.** Dois reenquadramentos dissolvem a maior parte da confusão: quem aplica é o *navegador* (não o servidor — por isso o curl funciona), e quem corrige é o *servidor* (não o seu frontend — por isso nenhuma quantidade de JavaScript ajuda). Todo o resto são headers.

## Principais pontos

| Pergunta | Resposta |
| --- | --- |
| A fundação | Política de same-origin: scripts não leem respostas de outras origens por padrão |
| Uma origin | esquema + host + porta — os três precisam bater |
| CORS | Headers do servidor fazendo opt-in de origens específicas; o navegador aplica |
| Preflight | Um OPTIONS "posso?" antes de requisições não simples |
| A verdade eterna | Erros de CORS se corrigem no servidor, ponto final |

## O protocolo inteiro, na rede

```text
# Preflight: o navegador pergunta antes de um PUT com header de autenticação
OPTIONS /classes/Product HTTP/1.1
Origin: https://app.example.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: x-parse-session-token

# A licença por escrito do servidor
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://app.example.com   ← esta origin pode ler
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: x-parse-session-token
Access-Control-Max-Age: 86400        ← cacheie esta resposta; pule o preflight de amanhã

# Então, e só então, a requisição real é enviada.
```

Como isso aparece no código da aplicação — e a verdade de plataforma que as abas ensinam: CORS é um assunto do *navegador*, que apps nativos nunca encontram:

**JavaScript:**

```javascript
// Browser JavaScript — Back4app JS SDK
// A cross-origin call that just works: the platform answers the
// preflight and sends the CORS headers, so the browser lets it through
Parse.initialize('APP_ID', 'JS_KEY');
Parse.serverURL = 'https://parseapi.back4app.com'; // different origin than your site

const products = await new Parse.Query('Product').find();
// No proxy hacks, no "disable CORS" — the server side is configured correctly.
```

**Flutter:**

```dart
// Flutter / Dart — Back4app Flutter SDK
// Native apps have no same-origin policy — CORS is a browser concern.
// Flutter Web, however, DOES enforce it: same browser rules apply there.
final query = QueryBuilder<ParseObject>(ParseObject('Product'));
final response = await query.query();
// Works identically on mobile and web because the server sends CORS headers.
```

**Swift:**

```swift
// iOS / Swift — Back4app Swift SDK
// No browser, no same-origin policy: CORS never applies to native iOS.
// The same backend serves browsers (with CORS headers) and apps alike.
let query = Product.query()
query.find { result in
  if case .success(let products) = result { render(products) }
}
```

**Kotlin:**

```kotlin
// Android / Kotlin — Back4app Android SDK
// No browser, no same-origin policy: CORS never applies to native Android.
// The same backend serves browsers (with CORS headers) and apps alike.
val query = ParseQuery.getQuery<ParseObject>("Product")
query.findInBackground { products, e ->
  if (e == null) render(products)
}
```

## O fluxo, decidido

```mermaid
flowchart TB
  accTitle: Como um navegador decide uma requisição cross-origin
  accDescr: Requisições same-origin prosseguem direto; requisições cross-origin simples são enviadas e a resposta é checada por um header allow-origin; requisições não simples disparam um preflight OPTIONS antes, e qualquer header ausente ou divergente faz o navegador bloquear a resposta para a página.
  R["Script faz uma requisição"] --> S{"Mesma origin?"}
  S -- sim --> OK["Prossegue, sem CORS envolvido"]
  S -- não --> T{"Requisição simples?<br/>(GET/HEAD/POST, headers na safelist)"}
  T -- sim --> D["Envia; checa na resposta o<br/>Access-Control-Allow-Origin"]
  T -- não --> P["Preflight OPTIONS primeiro"]
  P --> D
  D -->|"header bate com a origin"| OK2["Resposta legível"]
  D -->|"ausente / divergente"| B["Bloqueada pelo navegador<br/>(o erro do console)"]
```

Dois detalhes carregam a maioria das sessões de debug: uma **requisição simples** (GET/HEAD/POST com headers da safelist e content types comuns) pula o preflight — e é por isso que adicionar um header `Authorization` de repente "quebra" um endpoint que funcionava; e **requisições com credenciais** apertam tudo — cookies só fluem com `Access-Control-Allow-Credentials: true` *mais* uma origin exata, nunca o wildcard, conforme [a especificação](https://fetch.spec.whatwg.org/#http-cors-protocol).

## Como corrigir erros de CORS (erro → causa → correção)

| O console diz | O que realmente aconteceu | Correção (sempre server-side) |
| --- | --- | --- |
| No 'Access-Control-Allow-Origin' header | O servidor nunca fez opt-in da sua origin | Adicione sua origin à lista permitida |
| Origin not allowed by Access-Control-Allow-Origin | A allow-list existe; você não está nela | Adicione o esquema+host+porta exatos |
| Response to preflight… doesn't pass | OPTIONS sem tratamento ou headers incompletos | Responda o OPTIONS com métodos/headers |
| Wildcard '*' cannot be used with credentials | Cookies + `*` — combinação proibida | Liste as origens explicitamente |
| Request header not allowed | Header customizado fora da allow-list | Adicione-o ao Access-Control-Allow-Headers |

E o anti-fix que merece nome: desabilitar por flag de navegador e proxies permissivos de dev tornam o erro invisível *só na sua máquina* — o deploy continua quebrado para os usuários. A correção real é uma configuração de servidor medida em minutos.

## Casos de uso comuns

- **SPA + API em origens diferentes** — app.example.com chamando api.example.com: o caso cotidiano para o qual o CORS existe.
- **Desenvolvimento local** — localhost:3000 contra um backend real; permita a origin de dev, não desligue o escudo.
- **APIs públicas** — origin wildcard, sem credenciais: correto e seguro para dados genuinamente públicos.
- **Plataformas multi-frontend** — vários apps, um backend, uma lista explícita de origens por ambiente.
- **Backends BaaS** — a plataforma responde os preflights e envia os headers; seu trabalho se reduz a declarar as origens permitidas.

## Wildcard vs. origens explícitas: matriz de decisão

| Configuração | Certa quando… | Nunca quando… |
| --- | --- | --- |
| Wildcard `*` | API pública, sem credenciais | Existem cookies ou sessões de usuário |
| Lista explícita de origens | APIs privadas, apps com credenciais | — (esta é a resposta padrão) |
| Refletir a origin da requisição | Quase nunca | Combinada com credenciais — o buraco clássico |
| Listas por ambiente | Higiene de dev/staging/prod | Prod herdando as entradas localhost de dev |

Um reenquadramento de segurança fecha a matriz: CORS **não é controle de acesso** — apps nativos e servidores o ignoram por completo, então ele protege *usuários de navegador* contra sites maliciosos, não a sua API contra chamadores. Autenticação e [permissões na camada de dados](/glossary/data-layer-vs-application-layer-security/) fazem esse trabalho; o CORS só decide quais scripts de quais sites podem ler as respostas.

## Limitações e trade-offs

- **Só governa navegadores.** Qualquer coisa que não seja navegador passa direto — nunca confunda uma lista de origens com autorização.
- **Preflights custam um round trip** em requisições não simples; o cache via `Access-Control-Max-Age` é a correção barata e esquecida.
- **Má configuração falha fechada e barulhenta** — bom para a segurança, brutal para o debug sem a tabela erro→correção acima.
- **Listas de origens são estado de ambiente.** Origens de staging vazam para configs de produção; audite a lista como qualquer credencial.
- **CORS ≠ CSRF ≠ CSP.** Siglas vizinhas, defesas separadas — cookies ainda precisam de proteção SameSite/token, páginas ainda precisam de uma content policy, e o CORS cuida apenas da leitura cross-origin.

## CORS no Back4app

O Back4app é uma plataforma open-source de Backend as a Service (BaaS) que combina banco de dados gerenciado, APIs REST e GraphQL geradas automaticamente, autenticação, armazenamento de arquivos e funções serverless com Cloud Code. A tarefa do CORS já vem resolvida: as APIs da plataforma respondem preflights e enviam os headers corretos, então apps de navegador chamam o backend a partir das origens permitidas sem gambiarras de proxy — a aba JavaScript acima é a experiência inteira — enquanto as abas Flutter, Swift e Kotlin demonstram a verdade mais silenciosa: clientes nativos nunca encontram a cerimônia. A segurança real fica onde pertence: sessões, ACLs e permissões em nível de classe aplicadas server-side em toda requisição, venha de qual origem vier.
