🌐 Detecting your location…
📢 Advertisement — Configure AdSense in Appearance → Customize → AdSense Settings

Como corrigir o erro ‘Política CORS: Sem cabeçalho Access-Control-Allow-Origin’

⏱️5 min read  ·  1,034 words

O erro“O acesso para buscar em ‘…’ da origem ‘…’ foi bloqueado pela política CORS: Nenhum cabeçalho ‘Access-Control-Allow-Origin’ está presente” é um dos erros de desenvolvimento web mais comuns. É aplicado pelo navegador como um mecanismo de segurança. Aqui estão todas as causas e soluções.

Por que o CORS existe (compreensão necessária)

CORS (Cross-Origin Resource Sharing) evita que sites maliciosos façam solicitações à API do seu banco usando os cookies logados. Sem o CORS, visitar evil.com poderia fazer chamadas de API silenciosamente para yourbank.com com seus cookies de sessão. O navegador impõe CORS – os servidores declaram quais origens são permitidas.

CORS é um recurso de segurança do navegador — aplica-se apenas a solicitações iniciadas pelo navegador. Curl, Postman e solicitações de servidor para servidor não são afetadas pelo CORS.

Correção 1: Express.js – Usando o pacote cors

npm install cors
const express = require('express');
const cors    = require('cors');
const app     = express();

// ✅ Allow specific origin (recommended for production)
app.use(cors({
  origin:      'https://yourfrontend.com',
  methods:     ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
  allowedHeaders: ['Content-Type', 'Authorization'],
  credentials: true,   // required if frontend sends cookies/auth headers
}));

// ✅ Allow multiple origins
const allowedOrigins = ['https://app.example.com', 'https://admin.example.com'];
app.use(cors({
  origin: (origin, callback) => {
    if (!origin || allowedOrigins.includes(origin)) {
      callback(null, true);
    } else {
      callback(new Error(`Origin ${origin} not allowed by CORS`));
    }
  },
  credentials: true,
}));

// ❌ Allow all origins (never in production with credentials)
app.use(cors({ origin: '*' }));
// Note: wildcard '*' cannot be used with credentials: true

Correção 2: cabeçalhos CORS manuais no Express

// Without the cors package
app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', 'https://yourfrontend.com');
  res.header('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE,OPTIONS');
  res.header('Access-Control-Allow-Headers', 'Content-Type,Authorization');
  res.header('Access-Control-Allow-Credentials', 'true');

  // Handle preflight requests
  if (req.method === 'OPTIONS') {
    return res.status(204).end();
  }
  next();
});

Correção 3: proxy reverso Nginx

location /api/ {
    proxy_pass http://localhost:3000/;

    # CORS headers
    add_header 'Access-Control-Allow-Origin' 'https://yourfrontend.com' always;
    add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
    add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization' always;
    add_header 'Access-Control-Allow-Credentials' 'true' always;

    # Handle preflight
    if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' 'https://yourfrontend.com';
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain charset=UTF-8';
        add_header 'Content-Length' 0;
        return 204;
    }
}

Correção 4: Frontend – Modo de credenciais

// ❌ Fetch without credentials — cookies not sent
const res = await fetch('https://api.example.com/user');

// ✅ Include credentials (cookies, authorization headers)
const res = await fetch('https://api.example.com/user', {
  credentials: 'include',   // send cookies cross-origin
});

// For axios:
axios.defaults.withCredentials = true;
// Or per-request:
axios.get('/api/user', { withCredentials: true });

Importante: Quandocredentials: 'include', o servidor deve definirAccess-Control-Allow-Origin para a origem específica (não*) EAccess-Control-Allow-Credentials: true.

Noções básicas sobre solicitações de comprovação

Para solicitações “não simples” (PUT, DELETE, cabeçalhos personalizados, corpo do aplicativo/json), o navegador envia primeiro uma solicitação de simulação OPTIONS para verificar se a solicitação real é permitida. Se a simulação falhar, a solicitação real nunca será executada.

// Browser sends OPTIONS before POST with JSON body:
OPTIONS /api/users HTTP/1.1
Origin: https://frontend.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type

// Server must respond:
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://frontend.com
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: Content-Type
Access-Control-Max-Age: 86400  // cache preflight for 24 hours

Proxy de desenvolvimento (evite CORS durante o desenvolvimento)

// vite.config.ts — proxy /api to backend during dev
export default {
  server: {
    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, ''),
      }
    }
  }
};

// package.json (Create React App) — proxy all /api requests
{
  "proxy": "http://localhost:3000"
}

O proxy faz solicitações da mesma origem do frontend (do servidor de desenvolvimento), ignorando totalmente o CORS durante o desenvolvimento — sem comprometer a segurança da produção.

Erros Comuns

// ❌ Mistake 1: CORS headers on wrong route
app.get('/api/data', (req, res) => {
  res.header('Access-Control-Allow-Origin', '*');
  res.json(data);
});
// OPTIONS preflight hits a different handler that doesn't have CORS headers

// ❌ Mistake 2: Setting headers after response sent
app.use(cors());
app.get('/data', authenticate, (req, res) => {
  res.header('Access-Control-Allow-Origin', '*');  // Too late if cors() runs first
});

// ❌ Mistake 3: Multiple conflicting CORS headers
// Browser rejects when two Access-Control-Allow-Origin headers present
// Don't set CORS in both nginx AND Express — pick one place

Perguntas Frequentes

P: Posso desabilitar o CORS no navegador para desenvolvimento?
R: Sim:open -a "Google Chrome" --args --disable-web-security --user-data-dir="/tmp/chrome-dev". SOMENTE para desenvolvedores locais – nunca navegue em sites reais com esta sinalização. Usar um proxy é mais seguro e não requer a desativação da segurança.

P: Por que funciona no Postman, mas não no navegador?
R: O CORS só é aplicado por navegadores. Postman envia a solicitação diretamente sem uma verificação CORS do navegador. Isso confirma que seu servidor está funcionando – você só precisa adicionar cabeçalhos CORS.

P: Devo adicionar cabeçalhos CORS no aplicativo ou no proxy reverso?
R: Apenas um lugar. Se estiver usando o nginx, adicione cabeçalhos no nginx e não os adicione no Express (evita cabeçalhos duplicados). Se estiver implantando em um serviço sem controle nginx, adicione Express.

P: Por que minha API funciona na mesma origem, mas não em origens cruzadas?
R: Isso é exatamente o que o CORS impede: solicitações de origem cruzada exigem permissão explícita do servidor. Solicitações de mesma origem (frontend e API no mesmo domínio/porta) não precisam de cabeçalhos CORS.

P: Posso usar um serviço de proxy CORS?
R: Para prototipagem de desenvolvimento, serviços como cors-anywhere funcionam. Nunca para produção: você envia todas as suas solicitações de API por meio de um serviço de terceiros. Corrija o CORS corretamente em seu servidor.

Conclusão

Corrija o CORS adicionandoAccess-Control-Allow-Origin cabeçalhos em seu servidor – não desativando o CORS ou usando plug-ins de navegador. Para Express.js, ocors O pacote npm lida com todos os casos de forma limpa. Para Nginx, adicione cabeçalhos no nível do proxy. Para desenvolvimento, use a configuração de proxy do Vite para evitar totalmente o CORS. Sempre especifique origens exatas em vez de curinga* na produção, especialmente ao usar credenciais.

✍️ Leave a Comment

Your email address will not be published. Required fields are marked *

🌐 Read in:🇩🇪 Deutsch🇧🇷 Português🇸🇦 العربية🇮🇳 हिन्दी🇧🇩 বাংলা