Truques para depurar problemas de CORS em desenvolvimento local
1. Entendendo o Erro CORS: Sintomas e Causas Raiz
CORS (Cross-Origin Resource Sharing) é um mecanismo de segurança implementado pelos navegadores que restringe requisições HTTP entre diferentes origens. Uma origem é definida pela combinação de protocolo, domínio e porta. Por exemplo, http://localhost:3000 e http://localhost:5000 são origens diferentes.
Quando você vê o erro clássico no console:
Access to fetch at 'http://localhost:5000/api/data' from origin 'http://localhost:3000'
has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present
Isso significa que o servidor backend não incluiu o header necessário na resposta. Existem dois tipos principais de requisições CORS:
- Requisições simples: GET, HEAD, POST com content-type específicos. O navegador envia a requisição e verifica os headers na resposta.
- Requisições preflight: Quando usamos métodos como PUT/DELETE, headers customizados ou content-type
application/json, o navegador primeiro envia uma requisição OPTIONS para verificar permissões.
2. Configurando Headers CORS Manualmente no Backend
A forma mais básica de resolver CORS é adicionar headers manualmente na resposta do servidor. Exemplo em Node.js puro:
// Servidor HTTP básico com headers CORS
const http = require('http');
const server = http.createServer((req, res) => {
// Headers CORS manuais
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
// Responder requisições preflight
if (req.method === 'OPTIONS') {
res.writeHead(204);
res.end();
return;
}
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ message: 'Dados liberados' }));
});
server.listen(5000);
Para desenvolvimento, usar Access-Control-Allow-Origin: * é aceitável, mas lembre-se de restringir em produção.
3. Usando Middlewares e Configurações Específicas por Framework
Express.js (Node.js)
// Instalação: npm install cors
const express = require('express');
const cors = require('cors');
const app = express();
// CORS global para desenvolvimento
app.use(cors({
origin: 'http://localhost:3000',
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization']
}));
app.get('/api/data', (req, res) => {
res.json({ message: 'CORS configurado com Express' });
});
app.listen(5000);
FastAPI (Python)
# Instalação: pip install fastapi uvicorn
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:3000"],
allow_methods=["*"],
allow_headers=["*"],
)
@app.get("/api/data")
async def get_data():
return {"message": "CORS configurado com FastAPI"}
Hono.js (Bun)
import { Hono } from 'hono'
import { cors } from 'hono/cors'
const app = new Hono()
app.use('/*', cors({
origin: 'http://localhost:3000',
allowMethods: ['GET', 'POST', 'PUT', 'DELETE'],
allowHeaders: ['Content-Type', 'Authorization']
}))
app.get('/api/data', (c) => {
return c.json({ message: 'CORS configurado com Hono' })
})
export default app
4. Depurando com Ferramentas de Rede e Extensões do Navegador
O painel Network do DevTools é seu melhor amigo para depurar CORS:
- Abra o DevTools (F12) e vá para a aba "Network"
- Recarregue a página ou dispare a requisição
- Filtre por "XHR" ou "Fetch" para ver requisições de API
- Clique na requisição com erro (geralmente em vermelho)
- Na aba "Headers", verifique:
- Request Headers: Veja se
Originestá presente - Response Headers: Procure por
Access-Control-Allow-Origin - Status Code: 200 para sucesso, 204 para OPTIONS bem-sucedido
Extensões como "CORS Unblock" podem ajudar em testes rápidos, mas lembre-se de desativá-las em produção, pois elas desabilitam a segurança do navegador.
5. Simulando Cenários com Proxy Reverso Local
Uma abordagem elegante é configurar um proxy no seu servidor de desenvolvimento.
Vite (React/Vue/Svelte)
// vite.config.js
export default {
server: {
proxy: {
'/api': {
target: 'http://localhost:5000',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
}
}
http-proxy-middleware (Node.js)
// Instalação: npm install http-proxy-middleware
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
'/api',
createProxyMiddleware({
target: 'http://localhost:5000',
changeOrigin: true,
})
);
};
Testando com curl
# Teste direto sem CORS
curl -X GET http://localhost:5000/api/data -H "Origin: http://localhost:3000" -I
# Verifique se o header Access-Control-Allow-Origin aparece
6. Truques Avançados: Credenciais, Cookies e Headers Customizados
Quando você precisa enviar cookies ou autenticação, o cenário fica mais complexo:
// Backend - Express com credenciais
app.use(cors({
origin: 'http://localhost:3000',
credentials: true, // Permite cookies
allowedHeaders: ['Content-Type', 'Authorization', 'X-Request-ID']
}));
// Frontend - Fetch com credenciais
fetch('http://localhost:5000/api/data', {
method: 'GET',
credentials: 'include', // Envia cookies
headers: {
'Content-Type': 'application/json',
'X-Request-ID': '12345'
}
})
Importante: Quando credentials: true está ativo, Access-Control-Allow-Origin não pode ser *. Você deve especificar a origem exata.
7. Erros Comuns e Soluções Rápidas para Desenvolvimento Local
Mistura de HTTP e HTTPS
Se seu frontend roda em HTTPS (ex: https://localhost:3000) e o backend em HTTP (http://localhost:5000), o navegador bloqueia por segurança. Solução: use HTTP em ambos durante desenvolvimento ou configure certificados SSL locais.
Cache do Navegador
O navegador pode cachear respostas CORS antigas. Use:
- Hard Refresh: Ctrl+Shift+R (Windows/Linux) ou Cmd+Shift+R (Mac)
- Limpar Cache: DevTools > Network > Desmarcar "Disable cache" e recarregar
localhost vs 127.0.0.1
O navegador trata http://localhost:3000 e http://127.0.0.1:3000 como origens diferentes. Se seu frontend acessa localhost e o backend espera 127.0.0.1, haverá erro. Mantenha consistência.
8. Checklist Final e Automação para Evitar Dores de Cabeça
Script de inicialização com CORS aberto
// start-dev.sh
#!/bin/bash
export ALLOWED_ORIGINS="http://localhost:3000"
export NODE_ENV="development"
node server.js
Configuração de ambiente
// .env.development
ALLOWED_ORIGINS=http://localhost:3000,http://localhost:5173
CORS_CREDENTIALS=true
// server.js
const allowedOrigins = process.env.ALLOWED_ORIGINS.split(',');
app.use(cors({
origin: allowedOrigins,
credentials: process.env.CORS_CREDENTIALS === 'true'
}));
Testes automatizados com Supertest + Jest
// Instalação: npm install supertest jest --save-dev
const request = require('supertest');
const app = require('./app');
describe('CORS Headers', () => {
test('Deve retornar Access-Control-Allow-Origin', async () => {
const response = await request(app)
.get('/api/data')
.set('Origin', 'http://localhost:3000');
expect(response.headers['access-control-allow-origin'])
.toBe('http://localhost:3000');
});
test('Deve responder OPTIONS corretamente', async () => {
const response = await request(app)
.options('/api/data')
.set('Origin', 'http://localhost:3000')
.set('Access-Control-Request-Method', 'POST');
expect(response.status).toBe(204);
expect(response.headers['access-control-allow-methods'])
.toContain('POST');
});
});
Seguindo estes truques e configurações, você conseguirá depurar e resolver a maioria dos problemas de CORS em desenvolvimento local. Lembre-se: CORS é uma preocupação apenas do navegador — ferramentas como curl e Postman ignoram essas restrições, então use-as para verificar se sua API está funcionando corretamente independentemente do CORS.
Referências
- MDN Web Docs: CORS — Documentação completa sobre Cross-Origin Resource Sharing, incluindo exemplos de headers e cenários de erro.
- Express.js CORS Middleware — Documentação oficial do pacote
corspara Node.js, com opções de configuração detalhadas. - FastAPI CORS Middleware — Guia oficial de configuração de CORS no FastAPI com exemplos práticos.
- Vite Proxy Configuration — Documentação do Vite sobre configuração de proxy para desenvolvimento, útil para contornar CORS.
- Chrome DevTools Network Panel — Guia oficial do Google sobre como usar o painel Network para depurar requisições e headers.
- Hono.js CORS Middleware — Documentação oficial do middleware CORS para Hono.js, framework moderno para Bun.
- Supertest Documentation — Biblioteca para testes HTTP em Node.js, útil para validar headers CORS em testes automatizados.