POP HOSTING

Como ativar o CORS no site pelo arquivo htaccess, com exemplos seguros imprimir

  • cors, access-control-allow-origin, htaccess, preflight options, api php, vary origin
  • 0

Como liberar CORS no site pelo arquivo htaccess ou pelo PHP: exemplos seguros para fontes, imagens e APIs, com login e preflight OPTIONS.

  • Tempo: 10 min
  • Nível: Intermediário
  • Vale para: hospedagem cPanel com LiteSpeed ou Apache, sites e APIs em PHP
  • Atualizado: outubro de 2026

O CORS (Cross-Origin Resource Sharing) é a regra do navegador que decide se uma página de um endereço pode ler dados de outro endereço. Por padrão, um JavaScript rodando em https://app.seudominio.com.br não consegue ler a resposta de https://api.seudominio.com.br, nem uma fonte hospedada em https://cdn.seudominio.com.br. Para liberar, o servidor que entrega o arquivo precisa responder com o cabeçalho Access-Control-Allow-Origin.

Dois pontos que evitam muita confusão:

  • Quem bloqueia é o navegador. Por isso a mesma URL funciona no Postman, no curl ou no seu servidor e falha só na página.
  • O CORS não protege a sua API. Ele só controla o que páginas de outros sites conseguem ler no navegador do visitante. Autenticação continua sendo obrigatória.

Onde fazer a configuração

O cabeçalho vai no site que entrega o recurso (a API, a fonte, a imagem), não no site que faz o pedido. Na hospedagem cPanel, isso pode ser feito no .htaccess da pasta (para arquivos estáticos e casos simples) ou no próprio código PHP (para APIs, várias origens e login).

Exemplo 1: fontes, imagens e arquivos públicos para qualquer site

Use quando o conteúdo é público e não tem nada pessoal, como fontes web servidas de um subdomínio. No .htaccess da pasta onde estão os arquivos:

<IfModule mod_headers.c>
  <FilesMatch "\.(woff2?|ttf|otf|eot|svg|png|jpe?g|gif|webp|css|js)$">
    Header set Access-Control-Allow-Origin "*"
  </FilesMatch>
</IfModule>

O * libera qualquer origem. Isso é aceitável para arquivos estáticos públicos e é exatamente o que resolve o erro clássico de fonte bloqueada em subdomínio de CDN.

Exemplo 2: uma única origem autorizada

Quando só o seu outro site deve ler os dados, informe a origem exata (com https:// e sem barra no final):

<IfModule mod_headers.c>
  Header set Access-Control-Allow-Origin "https://app.seudominio.com.br"
  Header set Access-Control-Allow-Methods "GET, POST, OPTIONS"
  Header set Access-Control-Allow-Headers "Content-Type, Authorization"
  Header set Access-Control-Max-Age "600"
</IfModule>

O Max-Age diz ao navegador para guardar a autorização por 600 segundos e não repetir a consulta prévia (preflight) a cada pedido.

Exemplo 3: várias origens, login ou cookies (faça no PHP)

O cabeçalho Access-Control-Allow-Origin aceita uma origem só, ou *. Para autorizar uma lista, o servidor precisa ler a origem de quem pediu e devolver a mesma, se ela estiver na lista. Regras de SetEnvIf no .htaccess fazem isso no Apache, mas nem sempre se comportam igual no LiteSpeed. No código PHP funciona do mesmo jeito em qualquer servidor. Coloque no começo do arquivo da API (ou num arquivo incluído por todos os endpoints):

<?php
$permitidas = [
    'https://seudominio.com.br',
    'https://app.seudominio.com.br',
];
$origem = $_SERVER['HTTP_ORIGIN'] ?? '';

if (in_array($origem, $permitidas, true)) {
    header('Access-Control-Allow-Origin: ' . $origem);
    header('Access-Control-Allow-Credentials: true');
    header('Vary: Origin');
}

// Responde a consulta prévia (preflight) e encerra
if (($_SERVER['REQUEST_METHOD'] ?? '') === 'OPTIONS') {
    header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
    header('Access-Control-Allow-Headers: Content-Type, Authorization');
    header('Access-Control-Max-Age: 600');
    http_response_code(204);
    exit;
}
  • Allow-Credentials: true é necessário quando o front-end envia cookies ou usa fetch(…, { credentials: 'include' }). Com ele, a origem nunca pode ser *: o navegador recusa.
  • Vary: Origin avisa caches (LiteSpeed Cache, Cloudflare, proxies) que a resposta muda conforme a origem. Sem ele, um visitante pode receber o cabeçalho que foi gerado para outro site.
  • Preflight: pedidos com Content-Type: application/json, com Authorization ou com métodos como PUT e DELETE fazem antes uma consulta OPTIONS. Se ela não for respondida com os cabeçalhos certos, o pedido real nem é enviado.
Atenção: nunca faça "eco" de qualquer origem (header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']) sem conferir a lista) junto com Allow-Credentials: true. Isso deixa qualquer site do mundo ler os dados dos seus usuários logados.

Como testar

No navegador, abra a página que faz o pedido, tecle F12, vá na aba Network (Rede), clique no pedido e confira os cabeçalhos Access-Control-* da resposta. Pelo terminal, simule a origem com o curl:

curl -s -D - -o /dev/null -H "Origin: https://app.seudominio.com.br" https://api.seudominio.com.br/teste.php

E o preflight:

curl -s -D - -o /dev/null -X OPTIONS \
  -H "Origin: https://app.seudominio.com.br" \
  -H "Access-Control-Request-Method: POST" \
  https://api.seudominio.com.br/teste.php

Problemas comuns

No 'Access-Control-Allow-Origin' header is present on the requested resource

O cabeçalho não saiu. Confira se o .htaccess está na pasta certa (a do recurso, não a do site que pede), se a resposta é um erro 404 ou 500 (que muitas vezes sai sem o cabeçalho) e se o arquivo PHP não deu erro antes de chegar no header().

The 'Access-Control-Allow-Origin' header contains multiple values

O cabeçalho foi enviado duas vezes: pelo .htaccess e pelo PHP, ou por um plugin. Mantenha um lugar só. No .htaccess, use Header set (substitui) e não Header add (acumula).

Response to preflight request doesn't pass access control check

A consulta OPTIONS não foi respondida com sucesso. Garanta que o seu código trata o OPTIONS antes de exigir login, como no exemplo 3.

Funcionava e parou depois de ligar o cache

Falta o Vary: Origin ou o cache está guardando a resposta da API. APIs com dados de usuário normalmente não devem ser cacheadas.

Vai hospedar uma API ou um site com subdomínios? Conheça a hospedagem cPanel da POP Hosting, com SSL grátis e suporte em português.

Esta resposta lhe foi útil?
« Retornar