كيف يعمل ترميز كيانات HTML
كيان HTML هو مرجع حرف يُحلِّله المتصفح ويُعيده إلى حرف واحد. تحتاج الأحرف الخمسة المحجوزة في HTML (<، >، &، "، ') دائماً إلى ترميز عند عرض النص بصيغة HTML؛ أما البقية فاختيارية وتعتمد على ترميز المستند.
- اختر الوضع والنطاق. يمرّ وضع الترميز على الإدخال حرفاً حرفاً. أما وضع فكّ الترميز فيمسح الإدخال بحثاً عن أنماط الكيانات. يُحدّد مفتاح النطاق ما إذا كان سيُرمَّز الأحرف الخمسة الآمنة لـ HTML فقط، أو كل نقطة رمز غير ASCII أيضاً.
- اختر نمط الكيان. الكيانات المسمّاة (
©) مقروءة في الكود المصدري. المراجع العشرية (©) والسداسية (©) تحمل كل نقطة Unicode دون الحاجة إلى اسم. يفضّل عملاء البريد القديمون ومحلّلو XML الأشكال الرقمية. - مسح الإدخال. عند الترميز، نقرأ كل نقطة رمز ونبحث عنها في جدول مدمج يضم نحو 200 كيان مسمّى شائع؛ وما لا يُطابَق يُعاد إلى صيغة رقمية. عند فك الترميز، نمسح بتعبير منتظم واحد يُطابق
&name;و&#NNN;و&#xHH;في مرحلة واحدة. - تعيين الأحرف. تُحلَّل المطابقات المسمّاة عبر جدول عكسي. أما المطابقات الرقمية فتمرّ عبر
String.fromCodePointبالأساس 10 أو 16. تُترك الكيانات المسمّاة المجهولة دون تغيير حتى تجتاز الإدخالات الجزئية دورة ترميز كاملة دون فقدان. - الوضع المباشر. فعِّل الوضع المباشر وسيُعيد كل ضغطة مفتاح تشغيل التحويل مع تأخير 150 مللي ثانية. مفيد عند ضبط مقتطف والرغبة في تغذية راجعة فورية قبل لصقه في قالب.
لماذا نُرمِّز كيانات HTML
- منع إدخال المستخدم من إفساد التخطيط. حين يكتب مستخدم
<في حقل تعليق، يُعيد إدراج ذلك النص مباشرةً في HTML كتابةَ بقية الصفحة. ترميز الأحرف المحجوزة أولاً يجعل المتصفح يعرض الحرف بدلاً من تفسيره بداية وسم. - الحفاظ على صحة قيم الخصائص. تضمين سلسلة مُقتبسة داخل خاصية HTML يستلزم استبدال علامة الاقتباس المُضمَّنة بـ
"(للخصائص بعلامات مزدوجة) أو'(للخصائص بعلامات مفردة)، وإلا أغلق المحلّل الخاصية مبكراً وأصبح بقية السطر ترميزاً ضالاً. - تعطيل HTML العرضي في البيانات المُخزَّنة. كثيراً ما تحتوي السجلات وتقارير الأخطاء ومحادثات التصدير على أقواس زاوية وعلامات عطف حقيقية. ترميز الكيانات للإخراج قبل لصقه في صفحة توثيق يُبقي ذلك النص مرئياً بدلاً من تشغيل المُعالج أو كاشف الروابط التلقائي.
- مشاركة مقتطفات الكود بأمان. نشر وسم مثال كـ
<script>alert(1)</script>في مقالة مدوّنة أو بريد إلكتروني أو رسالة Slack يستلزم ترميز الأقواس حتى يُعرض المقتطف بدلاً من التنفيذ. تنطبق الطريقة ذاتها على أجسام موجز RSS وحقول `description` في JSON-LD.
التطبيقات الشائعة
يظهر ترميز الكيانات في أي مكان تُدمج فيه نصوص خام في HTML وقت التشغيل — حتى حين يُعالجها الإطار عادةً نيابةً عنك، تبقى الأداة اليدوية مفيدة حين لا يفعل.
- قوالب معالجة من جهة الخادم: Jinja2 وERB وTwig وHandlebars تُفلت تلقائياً بشكل افتراضي، لكن الكتل الخام ومُحدِّدات `safe` تُوقف ذلك — يتيح لك المحوّل التحقق مما كان الإفلات سيُنتجه.
- إنشاء البريد الإلكتروني والنشرات: كثير من محركات قوالب ESP لا تُفلت حقول الدمج تلقائياً، لذا تحتاج علامات الاقتباس الذكية ورموز حقوق النشر في الأسماء المُقدَّمة من المستخدم إلى ترميز مسبق.
- التوثيق ونماذج الكود: لصق وسم HTML مثالي في مقالة مدوّنة Markdown أو مقتطف موقع ثابت يستلزم ترميز الأقواس حتى يُعامله المُعالج كنص مرئي.
مثال عملي
الصق <script>alert('hi')</script> في حقل الإدخال مع ضبط الوضع على ترميز، النمط مسمّى، النطاق أدنى حدّ. تُنتج النتيجة <script>alert('hi')</script>. غيِّر النمط إلى السداسي الرقمي وسيُنتج الإدخال ذاته <script>alert('hi')</script>. اعكس الوضع إلى فك الترميز، والصق السلسلة المُرمَّزة، وستعود العلامة الأصلية سليمة.
FAQ
ما هي كيانات HTML؟
كيانات HTML هي مراجع أحرف يُعيدها المتصفح إلى أحرف فردية أثناء تحليله للصفحة. تأتي في ثلاثة أشكال: مسمّى (كـ & للرمز &)، عشري رقمي (&)، وسداسي رقمي (&). تحتاج الأحرف الخمسة المحجوزة في HTML (<، >، &، "، ') إلى ترميز في أي وقت تُدرج فيه النص في HTML. أما باقي نحو 2225 كياناً مسمّى فتشمل رموزاً ولهجات وحروفاً يونانية وهي اختيارية حين يكون ترميز المستند UTF-8.
متى أستخدم الكيانات المسمّاة مقابل الرقمية؟
استخدم الكيانات المسمّاة حين تريد أن يكون الكود المصدري مقروءاً (مُراجع يرى © في قالب يفهمه فوراً). استخدم الرقمية (عشرية أو سداسية) حين يكون المستهلك أقدم أو أكثر صرامة — يُدرك محلّلو XML وعملاء البريد القديمون وبعض قرّاء الموجزات مجموعة صغيرة فقط من كيانات HTML5 المسمّاة، بينما يُدركون جميعاً الأشكال الرقمية. يميل السداسي للفوز في السياقات الأمنية لأنه يتوافق مع تدوين نقطة Unicode المستخدمة في وثائق المواصفات.
هل يتعامل فك الترميز مع الكيانات السداسية كـ &؟
نعم. يستخدم المُفكِّك تعبيراً منتظماً واحداً يُطابق الأشكال الثلاثة للكيان في مرحلة واحدة: &name; و&#NNN; و&#xHH;. تُحلَّل المطابقات الرقمية بواسطة String.fromCodePoint بالأساس 10 أو 16. تُفكَّك المدخلات المختلطة (المسمّاة والرقمية في نفس السلسلة) بشكل صحيح، وتُترك الأسماء المجهولة كنص حرفي حتى تجتاز الإدخالات الجزئية دورة كاملة دون فقدان.
هل هذا آمن للاستخدام مع إدخال غير موثوق؟
المحوّل نفسه يعمل داخل المتصفح فقط ولا يُرسل إدخالك إلى أي مكان. أما سلامة المُخرجات للتضمين فتعتمد على السياق. يُعالج ترميز الكيانات سياقي جسم HTML وقيمة الخاصية، وهو ما يغطي حالة OWASP الأولى. أما سياقات JavaScript (معالجات الأحداث المُضمَّنة وكتل `<script>`) وسياقات CSS وسياقات URL فتحتاج كل منها إلى قواعد ترميزها الخاصة — ترميز الكيانات وحده لا يكفي هناك. للدفاع متعدد الطبقات من جهة الخادم، اجمع ذلك مع محرك قوالب يراعي السياق كـ DOMPurify أو آلية الإفلات التلقائي لإطارك.
يقع ترميز الكيانات من جهة المتصفح على الحدّ الفاصل بين إدخال المستخدم وHTML المُعروض. إجراء التحويل محلياً يعني أنك تستطيع التحقق مما كان إطارك سيُصدره، دون إرسال النص الأصلي إلى أي أداة خارجية.