Руководство по продукту
Проверка email в Node.js: от регулярных выражений к проверке доставляемости
Создайте проверку email в Node.js: локальный контроль формата, серверный API доставляемости и корректная обработка всех результатов.

Поток обработки в Node.js для проверки email: локальный контроль формата, серверная проверка доставляемости и четкая обработка каждого результата.
Проверка email в Node.js эффективнее всего работает как двухуровневый процесс на стороне сервера. Во-первых, нормализуйте ввод и проверьте его формат локально, чтобы очевидные опечатки не покидали ваш процесс. Во-вторых, вызовите проверку доставляемости, например, через POST /api/v1/check от EmailCheckPro из серверного кода с тайм-аутом, и разветвите логику на три исхода: Доставляемый, Недоставляемый или Не определено. Регулярное выражение лишь подтверждает, что адрес выглядит корректно; проверка доставляемости показывает, может ли адрес принять письмо в момент проверки, не отправляя на него никаких сообщений. Ссылки для подтверждения остаются отдельным шагом для получения согласия и проверки владения.
Что обычно означает проверка email в Node.js
Если искать эту тему, большинство руководств предлагают либо регулярное выражение, либо маршрут Express, который отправляет ссылку для подтверждения. Оба метода полезны, но они отвечают на разные вопросы, и их смешивание приводит к ошибкам.
| Уровень | На какой вопрос отвечает | Где выполняется |
|---|---|---|
| Контроль формата | Выглядит ли ввод как полный адрес? | Ваш процесс Node.js, без сетевого вызова |
| Проверка доставляемости | Может ли адрес принять почту в момент проверки? | Вызов серверного API |
| Ссылка для подтверждения | Владеет ли человек почтовым ящиком и согласен ли он на рассылку? | Отправляемое вами письмо и маршрут с токеном |
Это руководство охватывает первые два уровня, которые выполняются до того, как вы что-либо отправите. Они дополняют, а не заменяют процесс подтверждения. Эта модель повторяет проверку на уровне сервиса в других фреймворках: браузер может дать быстрые подсказки, но решение принимается на сервере, где хранятся API-ключ и результат.
Шаг 1: нормализация и контроль формата
Начните с небольшой предсказуемой функции. Удалите лишние пробелы, отбросьте знаки препинания в конце, которые часто попадают при копировании, приведите домен к нижнему регистру, а локальную часть оставьте как есть. Затем проверьте результат по общему шаблону.
// Шаблон из стандарта WHATWG HTML для полей type="email"
const EMAIL_PATTERN = /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
export function normalizeEmail(raw) {
const trimmed = String(raw ?? '').trim().replace(/[.,;:]+$/, '');
const at = trimmed.lastIndexOf('@');
if (at < 1 || at === trimmed.length - 1) return null;
const email = trimmed.slice(0, at) + '@' + trimmed.slice(at + 1).toLowerCase();
return EMAIL_PATTERN.test(email) ? email : null;
}
Шаблон взят из стандарта WHATWG HTML — того же правила, которое браузеры применяют к полям type="email", поэтому клиент и сервер работают согласованно. Если вы предпочитаете готовый пакет, isEmail в validator.js — популярный выбор; выберите один источник истины и используйте его везде.
Распространенные ошибки на этом уровне:
- Слишком строгие шаблоны, которые отвергают
+теги, длинные домены верхнего уровня или поддомены. Рекомендации OWASP советуют принимать широкий спектр корректных форматов и отклонять только явно ошибочный ввод. - Приведение всего адреса к нижнему регистру. Домены нечувствительны к регистру, но изменение локальной части искажает то, что ввел пользователь.
Шаг 2: вызов проверки доставляемости с сервера
В Node.js 18 и более поздних версиях есть глобальный fetch, поэтому HTTP-библиотека не требуется. Вызов должен выполняться на сервере: API-ключ расходует баланс аккаунта и никогда не должен попадать в код браузера.
const API_BASE = process.env.EMAILCHECK_API_BASE; // из документации API
export async function checkDeliverability(email) {
try {
const res = await fetch(`${API_BASE}/api/v1/check`, {
method: 'POST',
headers: buildHeaders(), // заголовки авторизации в точности как в документации
body: buildCheckBody(email), // тело запроса в точности как в документации
signal: AbortSignal.timeout(4000) // ваш бюджет времени
});
return await toOutcome(res); // 'deliverable' | 'undeliverable' | 'undetermined'
} catch (err) {
return 'not_completed'; // TimeoutError, сетевая ошибка и т.д.
}
}
buildHeaders, buildCheckBody и toOutcome — это вспомогательные функции, которые вы пишете на основе документации API EmailCheckPro, чтобы детали аутентификации и полей оставались в одном месте и следовали опубликованному контракту. toOutcome должна возвращать понятные слова, а не передавать сырые объекты ответа по кодовой базе.
AbortSignal.timeout() прерывает запрос по истечении выбранного вами бюджета и вызывает TimeoutError, что не дает медленной сети «заморозить» форму регистрации. Справочник fetch в Node.js перечисляет поддерживаемые опции. Выберите тайм-аут исходя из допустимого времени ожидания вашей формы; указанное выше значение — пример, а не системная величина.
Проверка доставляемости email принимает адреса практически на любом домене. Если продукту нужны публичные аватары, Проверка аватара email ограничена доменами Gmail, Yandex и Mail.ru, поэтому направляйте другие домены на продукт проверки доставляемости.
Шаг 3: обработка результатов «Доставляемый», «Недоставляемый» и «Не определено»
Представьте результат как небольшой набор состояний и позвольте форме принимать решение:
export async function screenSignupEmail(raw) {
const email = normalizeEmail(raw);
if (!email) return { ok: false, message: 'Пожалуйста, проверьте формат email.' };
const outcome = await checkDeliverability(email);
await saveCheck({ email, outcome, checkedAt: new Date() });
switch (outcome) {
case 'deliverable': return { ok: true, email };
case 'undeliverable': return { ok: false, message: 'Этот адрес не может принимать почту. Пожалуйста, используйте другой.' };
default: return { ok: true, email, flagged: true }; // undetermined или not completed
}
}
Почему каждая ветка ведет себя именно так:
- Доставляемый означает, что адрес мог принять почту в момент проверки. Продолжайте и сохраните дату вместе с результатом.
- Недоставляемый означает, что не мог. Попросите другой адрес в вежливой форме; не обвиняйте пользователя во вводе фальшивого адреса.
- Не определено охватывает адреса, которые невозможно однозначно классифицировать, например, catch-all адреса. API реального времени возвращает для них бизнес-код вместо результата, и они не тарифицируются. Примите адрес с пометкой, вместо того чтобы гадать.
- Не завершено охватывает тайм-ауты и сетевые ошибки. Позволяя пользователю продолжить с пометкой, вы не даете временной проблеме заблокировать реальную регистрацию.
Фоновая задача позже может перепроверить помеченные строки, а письмо для подтверждения, которое вы уже отправляете, прояснит ситуацию для многих из них.
Проверка нескольких адресов из Node.js
Формы регистрации проверяют один адрес, но инструменты администрирования и импорты часто содержат множество. Два задокументированных пути охватывают их.
До 100 адресов за раз. POST /api/v1/batch-check принимает 1–100 адресов и возвращает результаты в том же ответе, в порядке ввода. Разделите большие массивы на порции по 100 и сопоставьте каждый ответ с его порцией по позиции. Каждый элемент указывает, существует ли завершенный результат; элемент без него относится к ветке «Не определено» или «Не завершено», но никогда к «Недоставляемый».
Подготовленные файлы. Для экспорта и миграций создайте файл TXT или CSV с одним полным адресом на строку и отправьте его через POST /api/v1/bulk-tasks. Задача выполняется асинхронно, поэтому опрашивайте статус через воркер, а не через обработчик запросов:
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
async function waitForTask(taskRef) {
for (;;) {
const status = await getTaskStatus(taskRef); // GET /api/v1/bulk-tasks/{id}
if (status.done) return status; // успех или ошибка
await sleep(30_000); // никогда не опрашивайте чаще этого
}
}
Успешная задача предоставляет CSV-файл с результатами по ссылке для скачивания, которая действует 12 часов; повторный запрос той же задачи возвращает свежую ссылку. Некорректные и дублирующиеся строки удаляются при подготовке, поэтому объединяйте результаты обратно по email-адресу, а не по номеру строки. Лимиты задач для каждого продукта указаны в документации API.
Чек-лист для интеграции в Node.js
- Секреты: считывайте API-ключ из переменных окружения или менеджера секретов, не допускайте его попадания в логи и отчеты об ошибках.
- Кэширование: сохраняйте результат с датой и используйте его повторно в рамках вашего окна перепроверки, чтобы редактирование имени профиля не вызывало новый вызов.
- Ваш собственный эндпоинт: если приложение предоставляет маршрут проверки адреса, добавьте ограничение частоты запросов (rate limiting) и единообразные ответы, чтобы его нельзя было использовать для перебора существующих аккаунтов.
- Очереди: выполняйте перепроверку помеченных строк из очереди задач с задержкой и ограничением попыток, вместо повторных попыток внутри запроса.
- Тестирование: проводите модульное тестирование
normalizeEmailс использованием плюс-тегов, поддоменов, пробелов и отсутствующих доменов, а также тестируйте каждую ветку исхода с заглушкойcheckDeliverability, чтобы текст интерфейса был проверен до запуска. - AI-инструменты: команды, работающие с AI-ассистентами, могут использовать MCP-эндпоинт по адресу
https://emailcheckpro.com/mcpдля одиночных проверок и списков до 100 адресов, в то время как файловые задачи остаются на REST API.
Часто задаваемые вопросы
Достаточно ли регулярного выражения для проверки email в Node.js?
Регулярного выражения достаточно для выявления некорректного формата, и его следует запускать первым, так как это бесплатно. Команды, которым нужно знать, является ли адрес доставляемым, добавляют серверную проверку после регулярного выражения и оставляют ссылку для подтверждения для получения согласия и проверки владения.
Должна ли проверка доставляемости выполняться в браузере или на сервере?
На сервере. API-ключ расходует общий баланс аккаунта, поэтому его раскрытие во фронтенд-коде позволяет кому угодно использовать его. Серверный маршрут также может применять собственные ограничения частоты запросов, сохранять результат с датой и решать, как обрабатывать неопределенные или прерванные по тайм-ауту проверки. Браузер по-прежнему может показывать мгновенные подсказки по формату, используя тот же шаблон WHATWG.
Как команды могут избежать блокировки реальных пользователей, если результат проверки «Не определено»?
Примите адрес с пометкой вместо того, чтобы отклонять его. Неопределенные результаты, такие как catch-all адреса, не являются доказательством того, что адрес плохой, и они не тарифицируются. Помеченный аккаунт все еще может получить письмо для подтверждения; последующая задача может перепроверить его, а рассылочные конвейеры могут удерживать помеченные строки до получения завершенного результата или клика по ссылке подтверждения.
Узнать больше
Выберите информацию о продукте, которая соответствует следующему шагу в вашем рабочем процессе.