Нормализация email

Нормализация email в Validator.js позволяет привести адреса электронной почты к единому каноническому виду, устраняя различия, которые не влияют на фактическую доставку писем, но критичны для сравнения, хранения и дедупликации.

Основной инструмент — функция normalizeEmail, входящая в состав библиотеки Validator.js.

Адрес электронной почты может быть записан разными способами, хотя фактически указывать на один и тот же почтовый ящик. Наиболее распространённые вариации:

  • регистр символов в локальной части (User@Example.com и user@example.com)
  • точки в Gmail-адресах (u.ser@gmail.com и user@gmail.com)
  • подадресация через + (user+test@gmail.com)
  • особенности конкретных провайдеров (Outlook, Yahoo и др.)

Нормализация устраняет такие различия, приводя email к унифицированному виду.

Сигнатура функции normalizeEmail

normalizeEmail(email, options)
  • email — строка с адресом электронной почты
  • options — объект конфигурации нормализации

Функция возвращает нормализованный email или false, если входные данные некорректны.

Поведение по умолчанию

Без дополнительных настроек выполняется базовая нормализация:

  • приведение доменной части к нижнему регистру
  • приведение локальной части к нижнему регистру (в большинстве случаев)
  • удаление лишних символов пробелов

Пример:

const validator = require('validator');

validator.normalizeEmail('User@Example.COM');
// 'user@example.com'

Нормализация Gmail-адресов

Gmail имеет специфические правила обработки адресов, которые Validator.js учитывает отдельно.

Удаление точек

В Gmail точки в локальной части игнорируются:

validator.normalizeEmail('u.ser.name@gmail.com', {
  gmail_remove_dots: true
});
// 'username@gmail.com'

Удаление подадресации

Символ + и всё, что после него, игнорируется Gmail:

validator.normalizeEmail('username+test@gmail.com', {
  gmail_remove_subaddress: true
});
// 'username@gmail.com'

Совмещение правил

Обе опции часто используются вместе:

validator.normalizeEmail('U.ser+spam@gmail.com', {
  gmail_remove_dots: true,
  gmail_remove_subaddress: true
});
// 'user@gmail.com'

Приведение к нижнему регистру

Хотя доменная часть email всегда регистронезависима, локальная часть технически может быть чувствительной, но на практике почти всегда нормализуется.

validator.normalizeEmail('USER@EXAMPLE.COM', {
  all_lowercase: true
});
// 'user@example.com'

Особенности провайдеров

Validator.js учитывает различия между почтовыми сервисами, поскольку правила нормализации не универсальны.

Outlook / Hotmail

Поддерживается удаление подадресации:

validator.normalizeEmail('user+tag@outlook.com', {
  outlookdotcom_remove_subaddress: true
});
// 'user@outlook.com'

Yahoo

Yahoo также допускает подадресацию:

validator.normalizeEmail('user+tag@yahoo.com', {
  yahoo_remove_subaddress: true
});
// 'user@yahoo.com'

Объект options

Расширенная конфигурация позволяет управлять поведением нормализации:

  • all_lowercase
  • gmail_remove_dots
  • gmail_remove_subaddress
  • gmail_convert_googlemaildotcom
  • outlookdotcom_remove_subaddress
  • yahoo_remove_subaddress

Пример комплексной настройки

validator.normalizeEmail('User.Name+promo@GoogleMail.com', {
  all_lowercase: true,
  gmail_remove_dots: true,
  gmail_remove_subaddress: true,
  gmail_convert_googlemaildotcom: true
});

Результат:

'username@googlemail.com'

Конвертация googlemail.com и gmail.com

Google исторически использует два домена, которые являются взаимозаменяемыми. Опция позволяет унифицировать их:

validator.normalizeEmail('user@googlemail.com', {
  gmail_convert_googlemaildotcom: true
});
// 'user@gmail.com'

Практическое значение нормализации

Устранение дубликатов

При регистрации пользователей:

const emails = new Set();

emails.add(validator.normalizeEmail('user.name@gmail.com', {
  gmail_remove_dots: true
}));

emails.add(validator.normalizeEmail('username@gmail.com', {
  gmail_remove_dots: true
}));

// Set содержит только один email

Сравнение адресов

Без нормализации сравнение может давать ложные различия:

const a = 'user.name@gmail.com';
const b = 'username@gmail.com';

validator.normalizeEmail(a, { gmail_remove_dots: true }) ===
validator.normalizeEmail(b, { gmail_remove_dots: true });

Хранение в базе данных

Нормализованные email позволяют:

  • ускорить поиск
  • избежать дублей
  • упростить индексацию
  • снизить вероятность ошибок при авторизации

Ограничения нормализации

Нормализация не является универсальной операцией и зависит от домена:

  • не все провайдеры игнорируют точки или +
  • локальная часть email теоретически может быть чувствительной
  • правила могут меняться у конкретных сервисов

Validator.js решает эту проблему через раздельные стратегии для разных доменов, но полная универсальность невозможна.

Типичные ошибки при использовании

Игнорирование опций

validator.normalizeEmail('user.name@gmail.com');

В этом случае точки не удаляются, что может привести к дубликатам.

Применение Gmail-правил к другим доменам

Неправильное предположение, что все почтовые сервисы ведут себя как Gmail:

validator.normalizeEmail('user.name@domain.com', {
  gmail_remove_dots: true
});

Такое поведение может исказить данные.

Чрезмерная агрессивная нормализация

Удаление подадресации без учёта контекста может привести к потере информации о назначении email (например, фильтрации рассылок).

Внутренняя логика обработки

Validator.js выполняет нормализацию поэтапно:

  1. проверка валидности email
  2. разделение на локальную и доменную части
  3. применение доменно-специфичных правил
  4. обработка опций пользователя
  5. сборка итогового результата

Такая структура позволяет гибко расширять поддержку новых провайдеров без изменения базовой логики.

Совместное использование с validate

Часто normalizeEmail используется вместе с isEmail:

if (validator.isEmail(email)) {
  const normalized = validator.normalizeEmail(email);
}

Это обеспечивает предварительную проверку и последующую унификацию данных.