18 - Resolvendo o Problema de CORS na API

Quando tentamos conectar a nossa API a uma aplicação Front-end (como React, Angular, Vue ou até mesmo um arquivo HTML simples rodando localmente), o navegador costuma bloquear a comunicação por motivos de segurança, gerando um erro clássico no console. Hoje vamos entender o que é o CORS e como resolvê-lo de forma nativa no Go.

O que é CORS?

CORS significa Cross-Origin Resource Sharing (Compartilhamento de Recursos de Origem Cruzada). Trata-se de um mecanismo de segurança dos navegadores que impede que um site hospedado em uma origem (ex: http://localhost:5500) acesse os dados de uma API que está rodando em outra origem diferente (ex: http://localhost:8080), a menos que a API diga explicitamente que confia e permite esse acesso.

Para liberar o acesso, precisamos criar uma engrenagem que intercepta todas as requisições que chegam e adiciona cabeçalhos especiais de segurança informando que a nossa API está aberta para receber conexões externas. Chamamos essa engrenagem de Middleware.

Passo 1: Criando a função Middleware do CORS

Adicione a função abaixo no seu arquivo main.go (pode ser logo acima ou abaixo da sua função main). Ela interceptará os pedidos, injetará as permissões necessárias para o navegador e tratará de forma segura as requisições do tipo OPTIONS (conhecidas como Preflight):

// Função Middleware para gerenciar e liberar as permissões de CORS
func corsMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

		// 1. Permitir requisições de qualquer origem (Frontend)
		w.Header().Set("Access-Control-Allow-Origin", "*")

		// 2. Definir quais métodos HTTP externos são aceitos pela API
		w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")

		// 3. Definir os cabeçalhos permitidos nas requisições (obrigatório para JSON)
		w.Header().Set("Access-Control-Allow-Headers", "Content-Type")

		// 4. Tratar a requisição preflight (pedido de verificação prévia do navegador)
		if r.Method == http.MethodOptions {
			w.WriteHeader(http.StatusNoContent)
			return
		}

		// Se tudo estiver certo, passa a requisição adiante para as nossas rotas
		next.ServeHTTP(w, r)
	})
}

Passo 2: Atualizando a inicialização do Servidor

Agora que o nosso middleware está pronto, precisamos aplicá-lo para envelopar o roteador padrão do Go. Vá até a última linha da sua função main e substitua a chamada do ListenAndServe antiga por esta nova configuração:

// Configurar servidor aplicando o nosso middleware de CORS sobre o roteador padrão (http.DefaultServeMux)
http.ListenAndServe(":8080", corsMiddleware(http.DefaultServeMux))

Passo 3: Testando a Integração com o Front-end

Para testar se o CORS foi resolvido com sucesso, crie um arquivo HTML local no seu computador para simular um sistema Front-end realizando uma busca de dados (fetch) na sua API e exibindo os alunos cadastrados no terminal do navegador através de uma tabela.

Para facilitar os seus testes, você pode fazer o download do arquivo HTML pronto clicando no link abaixo:

Baixar Arquivo HTML de Testes

(Caso prefira criar o arquivo manualmente, utilize a estrutura de código abaixo):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Testar API</title>

    <!-- Script -->
    <script>
        // Realizar requisição para o nosso endpoint de listagem
        fetch("http://localhost:8080/alunos")
        .then(retornoAPI => retornoAPI.json())
        .then(alunos => console.table(alunos)) // Exibe os dados formatados em tabela no console do navegador
        .catch(erro => console.error("Erro ao conectar na API:", erro))
    </script>


    <h1>Abra o Console do Navegador (F12) para ver o resultado do teste!</h1>

Abra o arquivo HTML no seu navegador e pressione a tecla F12 para acessar a aba Console. Se o CORS estiver funcionando perfeitamente, você verá a tabela de alunos renderizada com sucesso, sem nenhuma mensagem vermelha de bloqueio!