اذهب إلى المحتوى

السؤال

نشر

لدي مكون React وفي داخلة أحاول أن أخزن عنصر HTML في متغير بالشكل التالي:

var myElement = '<div>simple text and <strong>strong text</strong></div>';

ثم أحاول أن أعرض هذا العنصر المُخزن في المتغير بالشكل التالي:

render: function() {
    return (
        <div className="container">{myElement}</div>
    );
}

كيف يمكنني أن أعرض العنصر السابق في DOM، سمعت عن دالة dangerouslySetInnerHTML ولكن أعتقد أنها تسبب مشكلة من نوع ما، هل يجب أن أستعملها؟

Recommended Posts

  • 0
نشر

يمكنك استخدام dangerouslySetInnerHTML  هكذا 

function createMarkup() {
  return {__html: '<div>simple text and <strong>strong text</strong></div>'};
}

function MyComponent() {
  return <div dangerouslySetInnerHTML={createMarkup()} />;
}

ولكن يجب أن تكون متأكد من المصدر الذي تحصل منه على ال html حتى لا تتعرض لاختراق ويمكنك القراءة بالتفصيل من التوثيق الرسمي

  • 0
نشر

يفضل بدلاً من string أن تستعمل الطريقة التالية مباشرةً:

const myElement = <div>simple text and <strong>strong text</strong></div>;

ما هذا ؟ منذ متى كنا نستطيع إسناد كود JSX إلى متحول؟

تذكر أن كود JSX ما هو في الحقيقة إلا استدعاء تابع من ReactJS والكود أعلاه يترجم إلى التالي:

const myElement = React.createElement("div", null, "simple text and ", React.createElement("strong", null, "strong text"));

إذاً فكود JSX ما هو إلا expression ويمكن إسناده لمتحول. هكذا نتجنب dangerouslySetInnerHTML والتي سميت بذلك ﻷنها تعرضك لخطر XSS الذي من خلاله قد يهكر شخص ما موقعك ليسرق بيانات مستخدم أو يظهر محتوى يشوه سمعة موقعك وغير ذلك.

أما إن كان كود HTML يأتي من دخل المستخدم كما هو الحال في HTML Editors فلا يوجد لديك خيار سوى استعمال dangerouslySetInnerHTML واتخاذ إجرائيات مختلفة للحماية ضد XSS مثل عمليات تحويل على كود HTML قبل عرضه أو غير ذلك من اﻷمور.

ملحوظة: بالنسبة للـReact.createElement فهو ينطبق على نسخة ReactJS 16 وما دون، مع ReactJS 17 أصبح اسم التابع مختلفاً ولكن هذا لا يهم لأن الفكرة هي نفسها.

  • 0
نشر

يمكنك عمل فلترة على النص المطلوب عرضه باستخدام دوال مساعدة مثل:

function encodeID(s) {
    if (s==='') return '_';
    return s.replace(/[^a-zA-Z0-9.-]/g, function(match) {
        return '_'+match[0].charCodeAt(0).toString(16)+'_';
    });
}

أو:

function encodeHTML(s) {
    return s.replace(/&/g, '&').replace(/</g, '<').replace(/"/g, '"');
}

حيث ستعمل على فلترة النص و استبدال أي محارف خاصة قد تسبب مشكلة.

حلول إضافية:

var ESC_MAP = {
    '&': '&amp;',
    '<': '&lt;',
    '>': '&gt;',
    '"': '&quot;',
    "'": '&#39;'
};

function escapeHTML(s, forAttribute) {
    return s.replace(forAttribute ? /[&<>'"]/g : /[&<>]/g, function(c) {
        return ESC_MAP[c];
    });
}

أو

function sanitize(string) {
  const map = {
      '&': '&amp;',
      '<': '&lt;',
      '>': '&gt;',
      '"': '&quot;',
      "'": '&#x27;',
      "/": '&#x2F;',
  };
  const reg = /[&<>"'/]/ig;
  return string.replace(reg, (match)=>(map[match]));
}

 

  • 0
نشر

استعمال dangerouslySetInnerHTML خطير جدا وأصلا الكلمة مصممة لافزاع المبرمج عند استخدامها والسؤال هنا لماذا والجواب ببساطة هو ليس في ان تنسيقات الصفحة قد تكون مخربة بل لأن ذلك ال html قد يكون يحمل معه أيضا javascript ويمكنني بسهولة أن ارسل لك كود html يحتوي على عنصر script فيه شيفرة تقرأ كل المداخل في موقعك وعند كل submition ل form سأقوب بطلب post على خادم تابع لي وليس لك وهكذا كل بيانات  مستخدمي موقعك ستكون تحت يدي لذا اياك واستخدامها من مصدر خارجي.

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...