Skip to content
العودة إلى المدوّنة
دروس تعليمية

شرح كيانات HTML: المسماة والرقمية ومتى تستخدم الهروب

دليل عملي لكيانات HTML: الفرق بين المراجع المسماة والعشرية والست عشرية، والأحرف الخمسة التي يجب الهروب منها، وقواعد السياق التي تمنع XSS.

8 دقائق للقراءة

كيان HTML هو طريقة لكتابة حرف بحيث يعرضه المتصفّح كنص بدلاً من معاملته كوسم (markup). اكتب < خاماً داخل محتواك فيبدأ المتصفّح بقراءة وسم؛ اكتب &lt; بدلاً منه فيُظهر < حرفياً على الصفحة. هذا التبديل هو جوهر فكرة ترميز كيانات HTML.

خمسة أحرف تحمل معنى خاصاً في HTML وهي الأكثر حاجةً للهروب: < و > و & و " و '. تهرب منها لسببين. الأول هو العرض: تريد إظهار شيفرة أو وسوم كنص. والثاني، وهو الأهم، هو الأمان: الهروب من المدخلات غير الموثوقة هو حجر الأساس في إيقاف هجمات البرمجة العابرة للمواقع (XSS).

هناك ثلاث طرق متكافئة لكتابة أي كيان — المسماة (&lt;) والعشرية (&#60;) والست عشرية (&#x3C;) — وكلها تؤول إلى الحرف نفسه. السؤال الأصعب هو متى تهرب وبماذا، لأن الإجابة الصحيحة تتوقف على المكان الذي تحطّ فيه القيمة: نص HTML، أو سمة (attribute)، أو سكربت، أو رابط (URL). يمر هذا الدليل عبر الترميزات، والمجموعة المحجوزة، ومصفوفة قرار حسب السياق، والمزالق التي توقع الناس أكثر من غيرها.

ما هو كيان HTML؟ (التشريح)

كيان HTML، ويُسمى أيضاً مرجع حرف (character reference)، هو رمز قصير يحلّ محل حرف واحد. كل كيان يبدأ بعلامة العطف & وينتهي بفاصلة منقوطة ;. وما يقع بينهما يحدد الحرف الذي تحصل عليه.

هناك ثلاثة أشكال:

  • &name; — مرجع مسمّى، مثل &lt; أو &copy;.
  • &#decimal; — مرجع رقمي عشري، مثل &#60;.
  • &#xhex; — مرجع رقمي ست عشري، مثل &#x3C;.

يقرأ المتصفّح المرجع، ويبحث عن الحرف الذي يشير إليه، ثم يعرض ذلك الحرف المفرد. لا شيء يتغير في النتيجة المرئية — &lt; و < الخام يُعرضان بشكل متطابق. الفرق الوحيد أن الكيان يُعامل كنص، لا كبداية وسم أبداً.

الترميزات الثلاثة: المسمّى، العشري، الست عشري

الترميزات الثلاثة جميعها تشير إلى نقطة شفرة (code point) يونيكود نفسها؛ وتختلف فقط في الإملاء. الكيان المسمّى هو الصيغة المقروءة لكنه موجود فقط للأحرف التي لها اسم معرَّف. الكيان العشري يكتب نقطة الشفرة في الأساس 10. والكيان الست عشري يكتب نقطة الشفرة نفسها في الأساس 16، وهو ما يُطابق واحداً لواحد ترميز U+XXXX الذي تراه في معيار يونيكود.

الحرفالمسمّىالعشريالست عشري
<&lt;&#60;&#x3C;
&&amp;&#38;&#x26;
©&copy;&#169;&#xA9;
é&eacute;&#233;&#xE9;

ولأن الست عشري يعكس U+XXXX مباشرةً — فـ é هو U+00E9، ومن ثَمّ &#xE9; — يلجأ إليه كثير من المطورين عند توثيق نقطة شفرة معيّنة أو الاستدلال عليها. أما للوسوم اليومية، فالكيانات المسمّاة هي الأسهل قراءةً.

الأحرف الخمسة المحجوزة التي يجب أن تهرب منها

هذه هي أحرف HTML الخاصة التي تغيّر كيفية تحليل المتصفّح للمستند. إن ظهر أحدها في محتوى يُفترض عرضه لا تنفيذه، فاهرب منه.

الحرفالمسمّىالعشريالست عشريما الذي يتعطّل إن لم تهرب منه
<&lt;&#60;&#x3C;يبدأ وسماً — فيقرأ المتصفّح النص التالي كوسوم (markup)
>&gt;&#62;&#x3E;يغلق وسماً قبل أوانه
&&amp;&#38;&#x26;يبدأ كياناً — فقد يُساء قراءة الباقي كمرجع
"&quot;&#34;&#x22;يُنهي قيمة سمة محاطة باقتباس مزدوج مبكراً
'&#x27;&#39;&#x27;يُنهي قيمة سمة محاطة باقتباس مفرد مبكراً

كيان علامة العطف في HTML هو جذر المنظومة كلها. فحرف & يبدأ كل كيان، لذا يجب الهروب منه أولاً — اهرب من القوسين الزاويين قبل علامة العطف فتُعيد الهروب من & في الكيانات التي أنشأتها للتو. مزيد عن هذا المزلق أدناه.

متى تحتاج فعلاً إلى الهروب؟ (وفق السياق)

هنا تسكن معظم العلل ومعظم الثغرات. المبدأ الأساسي قصير: اهرب عند وقت الإخراج، مطابقاً للسياق الذي تحطّ فيه القيمة. قيمة آمنة في مكان قد تكون خطرة في آخر، لذا يجب أن يطابق الترميز الذي تطبّقه الوجهةَ.

محتوى عنصر HTML

عندما تضع قيمة بين الوسوم — داخل <p> أو <div> أو <td> — اهرب من < و > و &. الهروب من علامتي الاقتباس هنا غير ضار لكنه غير ضروري. إن أردت إظهار النص <strong> كأحرف حرفية بدلاً من تحويل الكلمة التالية إلى عريضة، فرمّزه إلى &lt;strong&gt; فيطبع المتصفّح الوسم بدلاً من تطبيقه.

قيم سمات HTML

داخل السمة، يصبح حرفا الاقتباس حاسمين. إن سكنت قيمة في title="…" واحتوت على " غير مهروب منه، فإنها تُنهي السمة مبكراً وتتيح للمهاجم إلحاق سمات جديدة — وهو متجه XSS كلاسيكي. اهرب من " (والأفضل من ') في سياق السمة. قيمة مثل He said "hi" يجب أن تصبح He said &quot;hi&quot; لتبقى محصورة.

داخل <script> أو جافاسكربت المضمّنة

كيانات HTML لا تنفع هنا. السلسلة المبنية داخل كتلة <script> أو معالِج حدث مضمّن تحتاج إلى هروب سلسلة جافاسكربت أو JSON، لا إلى مراجع حرفية. كتابة &quot; داخل سلسلة JS حرفية تُنتج الأحرف الستة حرفياً، لا علامة اقتباس. لهذا السياق، استعن بأداة تهريب JSON، واقرأ الدليل الكامل لتهريب سلاسل JSON لقواعد \uXXXX التي تنطبق فعلاً داخل السكربت.

داخل رابط URL

للرابط (URL) مخطط هروب خاص به: ترميز النسبة المئوية (percent-encoding). كيانات HTML لن تجعل قيمةً آمنةً للرابط. السلسلة a&b c تنتمي إلى استعلام بصيغة a%26b%20c، لا a&amp;b c — فالمسافة لا تزال تكسر الرابط، و & لا يزال يفصل المعاملات. استخدم ترميز وفك ترميز URL لهذا، ودليل ترميز وفك ترميز URL للقواعد الكاملة حول الأحرف المحجوزة مقابل غير المحجوزة.

مصفوفة القرار

السياقتهرب بـمثالالخيار الخاطئ الذي يفشل
محتوى عنصر HTMLكيانات HTML (< > &)<strong>&lt;strong&gt;ترك < خاماً يحقن وسماً
قيمة سمة HTMLكيانات HTML (" ' حاسمان)"hi"&quot;hi&quot;علامة " غير مهروبة تكسر السمة
<script> / JS مضمّنةهروب سلسلة JS / JSON"\"كيانات HTML خاملة في JS
رابط URL / سلسلة استعلامترميز النسبة المئويةمسافة → %20&amp; والكيانات لا تزال تكسر الرابط

المسمّى مقابل الرقمي: أيهما تستخدم؟

الكيانات المسمّاة مقروءة وهي الافتراض الصحيح للأحرف المحجوزة الشائعة والرموز المعروفة — &lt; و &amp; و &copy; و &mdash;. لكنها لا توجد إلا للأحرف التي لها اسم معرَّف. أما الكيانات الرقمية، عشريةً كانت أم ست عشرية، فبإمكانها ترميز أي نقطة شفرة، بما فيها التي لا اسم لها، مما يجعلها البديل الشامل. وعندما لا تستطيع ضمان أن النظام المستهلِك يدعم كياناً مسمّى بعينه، فالرقمي هو الخيار الآمن.

لماذا الفاصلة العليا هي &#x27; وليست &apos;

الكيان المسمّى &apos; لم يُقدَّم إلا في HTML5 و XML. وهو غير معرَّف في HTML4، لذا تعرضه حفنة من المحللات وعملاء البريد القديمة كنص حرفي &apos; بدلاً من فاصلة عليا. أما المرجع الرقمي &#x27; — وتوأمه العشري &#39; — فيشير إلى الحرف نفسه تماماً، U+0027، ويفهمه كل محلل مطابق كُتب على الإطلاق. ومكتبات الهروب جيدة الاختبار مثل he تُصدر &#x27; للاقتباس المفرد لهذا السبب بالضبط، والمُرمِّز الجيد يتبع هذا العُرف ليكون الخرج آمناً للوضع في أي سياق HTML أو XML أو سمة.

مجموعة المحارف مقابل الكيانات: متى ترمّز غير الـ ASCII

مجموعة المحارف (charset)، مثل UTF-8، تقرر كيفية تخزين الأحرف كبايتات. أما الكيان فطريقة لتهجئة حرف باستخدام ASCII عادي فقط (& و # و ; والحروف والأرقام). هاتان طبقتان مختلفتان، والخلط بينهما يقود إلى ترميز لا داعي له.

على صفحة UTF-8 — أي تقريباً كل صفحة حديثة تعلن <meta charset="utf-8"> — تكون الحروف المُشكَّلة والشُّرَط والإيموجي أحرفاً خامّةً صالحة. اترك é و و 😀 كما هي تماماً. ترميز كل شيء إلى كيانات لا يهم إلا حين يجب أن ينجو النص من مجموعة محارف أحادية البايت قديمة أو نظام يُفسد UTF-8 الخام؛ وهناك وضع “ترميز كل ما هو غير ASCII” لتلك الحالات. وإن لم تكن متأكداً من علاقة البايتات بنقاط الشفرة والأحرف، فإن دليل ترميز UTF-8 و UTF-16 ويونيكود يعرض النموذج.

مزالق شائعة في كيانات HTML

الهروب من & أخيراً يسبب الهروب المزدوج

الترتيب مهم. إن استبدلت < و > قبل &، فإن الكيانات التي أنشأتها للتو (&lt; و &gt;) يُهرَب من علامة العطف & في بدايتها أيضاً، فينتهي < إلى &amp;lt; ويُعرض كنص حرفي &lt;. اهرب دائماً من & أولاً، ثم البقية. هذه القاعدة وحدها تمنع أشيع علة ترميز على الإطلاق.

الترميز المزدوج لنص مهروب منه أصلاً

تمرير نص مهروب منه أصلاً عبر مُرمِّز مرة أخرى يعيد ترميزه. فيصير &amp; إلى &amp;amp;، ويرى الزائر &amp; على الصفحة بدلاً من &. اهرب مرة واحدة بالضبط، عند وقت الإخراج. وإن مرّت قيمة عبر طبقات عدة، فتأكد أن واحدة منها فقط تُجري الهروب.

الموجيباكي عند فك الترميز

السير في الاتجاه الآخر له فخّه الخاص. افكك بمجموعة المحارف الخاطئة، أو افكك مرتين، فتحصل على خرج مشوّه — الموجيباكي (mojibake) الكلاسيكي. إن كانت صفحة تُظهر &amp;lt; حرفياً حيث توقعت <، فالصقها في مُفكِّك كيانات HTML لترى بالضبط إلام تؤول الكيانات؛ فهو يتعامل مع المسمّى والعشري والست عشري، وحتى المراجع القديمة غير المنتهية مثل &copy بلا فاصلة منقوطة لاحقة.

الثقة بالهروب علاجاً كاملاً لـ XSS

الهروب هو خط الدفاع الأول، لا الوحيد. ولأن لـ HTML سياقات عدة بقواعد مختلفة، فإن الهروب الموجَّه للسياق الخاطئ يترك ثغرة — علامات الاقتباس في السمات، وهروب JS في السكربت، وترميز النسبة المئوية في الروابط. اقرن الهروب الصحيح الواعي بالسياق مع سياسة أمان المحتوى (CSP) ومع الهروب التلقائي في إطار عملك. الكيانات هي الطبقة الأولى لا الأخيرة.

كيف ترمّز الكيانات وتفككها عملياً

حين تبني HTML يدوياً، تهرب منه بنفسك. إليك دالة escapeHtml() صحيحة تتعامل مع ترتيب & أولاً، إضافةً إلى الممارسة الأفضل لشيفرة التطبيقات الحقيقية.

// الأحرف الخمسة المحجوزة وكياناتها الآمنة:
//   <  →  &lt;     >  →  &gt;     &  →  &amp;     "  →  &quot;     '  →  &#x27;

function escapeHtml(str) {
  return str
    .replace(/&/g, '&amp;')   // & أولاً، حتى لا يُهرَب من الكيانات اللاحقة هروباً مزدوجاً
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#x27;'); // الصيغة الرقمية — آمنة في HTML4 و HTML5 و XML
}

const userInput = `<a href="x">Tom & Jerry's</a>`;
const safe = escapeHtml(userInput);
// → &lt;a href=&quot;x&quot;&gt;Tom &amp; Jerry&#x27;s&lt;/a&gt;

// أفضل في شيفرة التطبيقات: دع المنصة تهرب نيابةً عنك.
//   el.textContent = userInput;   // المتصفّح يهرب؛ بلا استبدال يدوي
//   React / Vue / Angular تهرب من النص المُدرَج افتراضياً
//   قوالب الخادم (Jinja, ERB, Blade) تهرب تلقائياً ما لم تختر الانسحاب

الدالة المكتوبة يدوياً مفيدة لفهم ما يحدث وللتحويلات لمرة واحدة، لكن في الإنتاج فضّل المسار المدمج. تعيين element.textContent يدع المتصفّح يهرب نيابةً عنك، وأطر العمل الحديثة تهرب من القيم المُدرَجة تلقائياً. اقصُر الهروب اليدوي على الحالات التي لا تغطيها المنصة.

للعمل الموضعي، يهرب مُرمِّز كيانات HTML من المجموعة المحجوزة (مسمّاةً أو عشريةً أو ست عشرية)، ويعكسه مُفكِّك كيانات HTML. والاثنان معكوسان تماماً للأحرف المحجوزة، فيمكنك تدوير النص عبرهما ذهاباً وإياباً بلا فقد.

الأسئلة الشائعة

ما هو كيان HTML؟

كيان HTML هو رمز قصير، يبدأ بـ & وينتهي بـ ;، يمثّل حرفاً واحداً. يعرض المتصفّح الحرف الذي يشير إليه الكيان بدلاً من معاملته كوسم. مثلاً، &lt; يعرض < حرفياً، و &amp; يعرض & حرفياً.

ما الأحرف التي أحتاج إلى الهروب منها في HTML؟

أحرف HTML الخاصة المحجوزة الخمسة: < و > و & و " و '. في محتوى العنصر تحتاج أساساً إلى < و > و &؛ وفي قيم السمات يصبح حرفا الاقتباس " و ' حاسمين أيضاً. اهرب من علامة العطف & أولاً حتى لا تُهرَب الكيانات الأخرى هروباً مزدوجاً.

هل أستخدم الكيانات المسمّاة أم الرقمية (العشرية/الست عشرية)؟

استخدم الكيانات المسمّاة (&lt; و &copy;) للوضوح مع الأحرف الشائعة، فهي سهلة التمييز. واستخدم الكيانات الرقمية (العشرية &#60; أو الست عشرية &#x3C;) حين تحتاج إلى ترميز حرف لا اسم معرَّف له، أو حين لا تستطيع ضمان دعم المستهلِك لكيان مسمّى بعينه. وكلتا الصيغتين تشيران إلى نقطة الشفرة نفسها.

هل تحمي كيانات HTML من XSS؟

هي الأساس، حين تُطبَّق بصورة صحيحة. الهروب من الأحرف المحجوزة الخمسة قبل وضع مدخلات غير موثوقة في محتوى عنصر أو سمة HTML يوقف حقن الوسوم والسكربت. لكن الهروب يتوقف على السياق: كتل السكربت تحتاج هروب جافاسكربت، والروابط تحتاج ترميز النسبة المئوية. اجمع بين الهروب الصحيح الواعي بالسياق وسياسة أمان المحتوى (CSP) والهروب التلقائي في إطار العمل.

لماذا تُظهر صفحتي &amp;lt; بدلاً من <؟

هذا هروب مزدوج. رُمِّز النص مرتين، أو هُرِب من & بعد القوسين الزاويين، فتحوّل & في &lt; إلى &amp;. عندئذ يرى الزائر &lt; كنص حرفي. اهرب مرة واحدة بالضبط واهرب دائماً من & أولاً. وبإمكان أداة فك الترميز أن تؤكد إلام تؤول الكيانات.

هل أحتاج إلى الهروب من أحرف مثل é أو — أو الإيموجي؟

غالباً لا. على صفحة تعلن <meta charset="utf-8">، تكون الحروف المُشكَّلة والشُّرَط والإيموجي أحرفاً خامّةً صالحة ولا تحتاج إلى ترميز — اتركها كما هي. لا ترمّز غير الـ ASCII إلا حين يجب أن يمر النص عبر مجموعة محارف أحادية البايت قديمة أو نظام يُفسد UTF-8 الخام.

الوسوم: HTML Encoding Security Web

مقالات ذات صلة

عرض جميع المقالات