Guia Completo de Estratégias para Cross-Origin no Desenvolvimento Front-end

O que é Cross-Origin?

O conceito de cross-origin refere-se a situações em que um documento ou script carregado de uma origem tenta interagir com um recurso de outra origem. No contexto web, uma "origem" é definida pela combinação de protocolo, domínio e porta. A restrição fundamental é imposta pela Política de Mesma Origem (Same-Origin Policy - SOP). Introduzida originalmente pela Netscape em 1995, essa política é uma medida crítica de segurança que impede que scripts maliciosos acessem dados confidenciasi de outros domínios, prevenindo ataques como XSS (Cross-Site Scripting) e CSRF (Cross-Site Request Forgery). A SOP restringe as seguintes interações entre origens diferentes: - Acesso ao DOM ou objetos JavaScript de outras janelas/iframes.

  • Leitura de cookies, LocalStorage ou IndexedDB.
  • Envio de requisições via XMLHttpRequest ou Fetch API (AJAX).

Cenários Comuns de Bloqueio

URL de Origem (A) URL de Destino (B) Resultado Motivo
http://meusite.com/inicio.js http://meusite.com/dados.json Permitido Mesma origem
http://meusite.com/app.js https://meusite.com/api Bloqueado Protocolos diferentes (http vs https)
http://meusite.com:8080/js http://meusite.com:9000/api Bloqueado Portas diferentes
http://vendas.meusite.com http://blog.meusite.com Bloqueado Subdomínios diferentes

Soluções para Comunicação entre Origens

1. JSONP (JSON with Padding)

Embora antigo, o JSONP aproveita o fato de que tags <script> não são bloqueadas pela SOP. Ele funciona injetando um script dinamicamente que executa uma função de retorno predefinida. Implementação no Cliente:```

const scriptElement = document.createElement('script'); scriptElement.type = 'text/javascript';

// Define o callback e passa parâmetros na URL scriptElement.src = 'https://api.externa.com/get-dados?id=123&callback=processarResposta'; document.head.appendChild(scriptElement);

function processarResposta(data) { console.log('Dados recebidos:', data); }


**Exemplo de Resposta do Servidor:**```

processarResposta({"status": "sucesso", "valor": 1500});

Nota: O JSONP suporta apenas o método GET.#### 2. CORS (Cross-Origin Resource Sharing)

É o padrão moderno e recomendado. O servidor define cabeçalhos HTTP que informam ao navegador quais origens têm permissão para acessar os recursos. Configuração no Cliente (com suporte a Cookies):```

const requisicao = new XMLHttpRequest(); // Habilita o envio de cookies para o domínio cruzado requisicao.withCredentials = true;

requisicao.open('POST', 'https://api.servico.com/v1/auth', true); requisicao.setRequestHeader('Content-Type', 'application/json'); requisicao.send(JSON.stringify({ user: 'admin' }));

requisicao.onreadystatechange = function() { if (requisicao.readyState === 4 && requisicao.status === 200) { console.log(requisicao.responseText); } };


**Configuração no Servidor (Exemplo Node.js/Express):**```

res.writeHead(200, {
    'Access-Control-Allow-Origin': 'https://meu-frontend.com',
    'Access-Control-Allow-Credentials': 'true',
    'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
    'Content-Type': 'application/json'
});

3. postMessage API

Ideal para comunicação entre janelas, abas ou iframes de origens diferentes. Envio (Página Principal):```

const frame = document.getElementById('meuIframe'); const payload = { acao: 'atualizar', id: 50 };

frame.contentWindow.postMessage(JSON.stringify(payload), 'https://dominio-do-iframe.com');


**Recepção (Dentro do Iframe):**```

window.addEventListener('message', function(event) {
    // Verificação de segurança da origem
    if (event.origin !== 'https://dominio-esperado.com') return;

    const dados = JSON.parse(event.data);
    console.log('Mensagem recebida:', dados);

    // Opcional: Responder de volta
    event.source.postMessage('Recebido!', event.origin);
}, false);

4. Proxy Reverso com Nginx

O Nginx atua como um intermediário. O navegador faz a requisição para o mesmo domínio do front-end, e o Nginx a encaminha para o backend real, mascarando a diferença de origem. Configuração do Nginx:```

server { listen 80; server_name meu-app.com;

location /api/ {
    # Encaminha as chamadas de /api/ para o backend real
    proxy_pass http://backend-interno:8080/;
    
    # Reescreve o domínio do cookie para o domínio do front
    proxy_cookie_domain backend-interno meu-app.com;

    # Adiciona cabeçalhos CORS se necessário
    add_header Access-Control-Allow-Origin "http://meu-app.com";
    add_header Access-Control-Allow-Credentials true;
}

}


#### 5. Proxy em Ambiente de Desenvolvimento (Webpack/Vite)

Ferramentas de build modernas como Webpack e Vite possuem servidores de desenvolvimento que podem atuar como proxies locais. **Configuração Webpack (webpack.config.js):**```

module.exports = {
    devServer: {
        proxy: {
            '/api': {
                target: 'http://api.servidor-remoto.com',
                changeOrigin: true,
                pathRewrite: { '^/api': '' },
                secure: false
            }
        }
    }
};

6. document.domain

Esta técnica é limitada apenas a domínios que compartilham o mesmo domínio base (ex: vendas.site.com e loja.site.com). Em ambas as páginas:```

// Força o domínio base comum document.domain = 'site.com';


Isso permite que scripts de uma página acessem o DOM da outra via `window.parent` ou `window.frames`. #### 7. WebSockets

Diferente das requisições HTTP tradicionais, o protocolo WebSocket (ws:// ou wss://) não impõe a Política de Mesma Origem por padrão. O servidor WebSocket deve verificar o cabeçalho `Origin` durante o handshake para decidir se aceita a conexão. ```

const socket = new WebSocket('ws://api.realtime.com:8080');

socket.onopen = () => {
    socket.send('Iniciando comunicação cross-domain');
};

socket.onmessage = (event) => {
    console.log('Mensagem do servidor:', event.data);
};

Tags: CORS javascript nginx WebSecurity frontend

Publicado em 8-25 05:26