التحقق من صحة البريد الإلكتروني في JavaScript: كيف يعمل تحت الغطاء (تحليل الكود)

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

كيفية التحقق من صحة البريد الإلكتروني في JavaScript: من التعبير المنتظم البسيط إلى التحليل الكامل تحت الغطاء

\n\n

كل مطور واجه مرة واحدة على الأقل في حياته السؤال: «How can I validate an email address in JavaScript?». هذا السؤال على Stack Overflow جمع آلاف المشاهدات ومئات الإجابات، لأن الموضوع عبارة عن كتلة متشابكة من التفاصيل الدقيقة. اليوم لن نقدم فقط كودًا جاهزًا، بل سننظر تحت الغطاء: سنحلل لماذا قد يمرر الفحص البسيط a@b أو يحظر "test@[IPv6:2001:db8::1]". هيا بنا!

\n\n

لماذا «التعبير المنتظم البسيط» فكرة سيئة؟

\n\n

الحل الأكثر شيوعًا على الإنترنت هو نسخ تعبير منتظم. لكن لنكن صادقين: عناوين البريد الإلكتروني هي فوضى. المواصفات RFC 5321 و RFC 5322 تسمح باستخدام الرموز +, -, ., % وحتى التعليقات بين قوسين. وهناك أيضًا نطاقات مثل museum أو @[192.168.1.1]. حاول وضع كل هذا في سطر واحد من التعبير المنتظم - وإما أن تترك عنوانًا صحيحًا أو تحظر مستخدمًا حقيقيًا.

\n\n

هذا مثال شائع على Stack Overflow:

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

هذا الكود يعمل في 90% من الحالات، لكن:

\n
    \n
  • يترك test@localhost (صحيح للشبكة المحلية)
  • \n
  • يحظر "test@[192.168.1.1]" (صحيح حسب RFC)
  • \n
  • لا يتحقق من طول النطاق أو وجود النقاط
  • \n
\n\n

الخلاصة: لا تحاول كتابة تعبير منتظم مثالي. من الأفضل استخدام مزيج من الفحص البسيط + التحقق من الخادم.

\n\n

تشريح عنوان البريد الإلكتروني: ما تحتاج معرفته قبل كتابة الكود

\n\n

قبل كتابة أداة التحقق، دعنا نحلل هيكل البريد الإلكتروني حسب المواصفات:

\n\n
    \n
  • الجزء المحلي (قبل @): يمكن أن يحتوي على حروف وأرقام ونقاط وإشارات زائد وشرطات، لكن لا يمكن أن يبدأ أو ينتهي بنقطة. علامات الاقتباس مسموحة للرموز الخاصة.
  • \n
  • النطاق (بعد @): يتكون من تسميات مفصولة بنقاط. كل تسمية من 1 إلى 63 حرفًا. يمكن أن يكون النطاق عنوان IP بين قوسين مربعين.
  • \n
  • الطول الإجمالي: لا يزيد عن 254 حرفًا.
  • \n
\n\n

بمعرفة هذا، يمكننا كتابة فحص أكثر معنى.

\n\n

الخطوة 1: تحقق بسيط لكن عملي (لـ 99% من الحالات)

\n\n

لنبدأ بالكود المستخدم في المشاريع الحقيقية (مثل Angular أو React). إنه ليس مثاليًا، لكنه كافٍ لمعظم النماذج:

\n\n
function isEmailSimple(email) {\n    // إزالة المسافات\n    const trimmed = email.trim();\n    \n    // التحقق من السلسلة الفارغة\n    if (!trimmed) return false;\n    \n    // الهيكل الأساسي: شيء @ شيء . شيء\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    // يجب أن يحتوي النطاق على نقطة واحدة على الأقل\n    const dotIndex = domain.lastIndexOf('.');\n    if (dotIndex < 1 || dotIndex === domain.length - 1) return false;\n    \n    // التحقق من الطول\n    if (trimmed.length > 254) return false;\n    if (localPart.length > 64) return false;\n    \n    return true;\n}\n\n// أمثلة:\nconsole.log(isEmailSimple('user@example.com')); // true\nconsole.log(isEmailSimple('a@b.c')); // true (صحيح رسميًا)\nconsole.log(isEmailSimple('user@localhost')); // false (لا توجد نقطة)\nconsole.log(isEmailSimple('@example.com')); // false\n
\n\n

هذا الكود أفضل بالفعل من التعبير المنتظم الأعمى. إنه يتحقق من الهيكل والطول ووجود @ مع نقطة. لكنه يترك user@[192.168.1.1] - وهذا ليس حرجًا لمعظم نماذج الويب.

\n\n

الخطوة 2: تحقق متقدم مع مراعاة RFC (تقريبًا كما في المتصفح)

\n\n

المتصفحات الحديثة تستخدم التحقق المدمج عبر السمة type="e

المدونات

توصيات الكتب