Validação de email em JavaScript: como funciona por baixo dos panos (análise de código)

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Como validar email em JavaScript: do regex simples à análise completa por baixo dos panos

\n\n

Todo desenvolvedor já se deparou pelo menos uma vez com a pergunta: «How can I validate an email address in JavaScript?». Esta pergunta no Stack Overflow acumulou milhares de visualizações e centenas de respostas, porque o tema é um verdadeiro emaranhado de nuances. Hoje não vamos apenas fornecer um código pronto, mas vamos olhar por baixo dos panos: analisar por que uma verificação simples pode deixar passar a@b ou bloquear "test@[IPv6:2001:db8::1]". Vamos nessa!

\n\n

Por que «apenas regex» é uma má ideia?

\n\n

A solução mais popular na internet é copiar uma expressão regular. Mas sejamos honestos: endereços de email são um caos. A especificação RFC 5321 e RFC 5322 permite o uso de caracteres como +, -, ., % e até comentários entre parênteses. Além disso, existem domínios como museum ou @[192.168.1.1]. Tente colocar tudo isso em uma única linha de regex — e você ou deixará passar um endereço válido ou bloqueará um usuário real.

\n\n

Aqui está um exemplo que aparece com frequência no Stack Overflow:

\n\n
const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;
\n\n

Este código funciona para 90% dos casos, mas:

\n
    \n
  • Deixa passar test@localhost (válido para rede local)
  • \n
  • Bloqueia "test@[192.168.1.1]" (válido segundo RFC)
  • \n
  • Não verifica o comprimento do domínio ou a presença de pontos
  • \n
\n\n

Moral da história: não tente escrever um regex perfeito. É melhor usar uma combinação de verificação simples + validação no servidor.

\n\n

Anatomia de um endereço de email: o que saber antes de escrever o código

\n\n

Antes de escrever um validador, vamos analisar a estrutura de um email de acordo com a especificação:

\n\n
    \n
  • Parte local (antes do @): pode conter letras, números, pontos, sinais de mais, hífens, mas não pode começar ou terminar com ponto. Aspas são permitidas para caracteres especiais.
  • \n
  • Domínio (após o @): consiste em rótulos separados por pontos. Cada rótulo tem de 1 a 63 caracteres. O domínio pode ser um endereço IP entre colchetes.
  • \n
  • Comprimento total: não mais que 254 caracteres.
  • \n
\n\n

Sabendo disso, podemos escrever uma verificação mais significativa.

\n\n

Passo 1: Validação simples, mas funcional (para 99% dos casos)

\n\n

Vamos começar com o código usado em projetos reais (por exemplo, em Angular ou React). Não é perfeito, mas é suficiente para a maioria dos formulários:

\n\n
function isEmailSimple(email) {\n    // Remove espaços\n    const trimmed = email.trim();\n    \n    // Verifica se é string vazia\n    if (!trimmed) return false;\n    \n    // Estrutura básica: algo @ algo . algo\n    const atIndex = trimmed.lastIndexOf('@');\n    if (atIndex < 1 || atIndex === trimmed.length - 1) return false;\n    \n    const localPart = trimmed.slice(0, atIndex);\n    const domain = trimmed.slice(atIndex + 1);\n    \n    // Domínio deve conter pelo menos um ponto\n    const dotIndex = domain.lastIndexOf('.');\n    if (dotIndex < 1 || dotIndex === domain.length - 1) return false;\n    \n    // Verificação de comprimento\n    if (trimmed.length > 254) return false;\n    if (localPart.length > 64) return false;\n    \n    return true;\n}\n\n// Exemplos:\nconsole.log(isEmailSimple('user@example.com')); // true\nconsole.log(isEmailSimple('a@b.c')); // true (formalmente válido)\nconsole.log(isEmailSimple('user@localhost')); // false (sem ponto)\nconsole.log(isEmailSimple('@example.com')); // false\n
\n\n

Este código já é melhor do que um regex cego. Ele verifica a estrutura, o comprimento e a presença de @ com ponto. Mas ele deixa passar user@[192.168.1.1] — para a maioria dos formulários web, isso não é crítico.

\n\n

Passo 2: Validação avançada considerando RFC (quase como no navegador)

\n\n

Navegadores modernos usam validação embutida através do atributo type="e

Blogs

Book Recommendations