React.js: आंतरिक HTML बनाम खतरनाक तरीके से सेट करें InnerHTML


171

क्या किसी तत्व के आंतरिक HTML सेट करने से किसी तत्व के खतरनाक तरीके से सेट करने पर "पर्दे के पीछे" अंतर होता है? मुझे लगता है कि मैं सादगी के लिए चीजों को अच्छी तरह से साफ कर रहा हूं।

उदाहरण:

var test = React.createClass({
  render: function(){
    return (
      <div contentEditable='true' dangerouslySetInnerHTML={{ __html: "Hello" }}></div>
    );
  }
});

बनाम

var test = React.createClass({
  componentDidUpdate: function(prevProp, prevState){
    this.refs.test.innerHTML = "Hello";
  },
  render: function(){
    return (
      <div contentEditable='true' ref='test'></div>
    );
  }
});

मैं उपरोक्त उदाहरण की तुलना में कुछ अधिक जटिल कर रहा हूं, लेकिन समग्र विचार समान है

जवाबों:


237

हां, वहां एक अंतर है!

innerHTMLबनाम का उपयोग करने का तत्काल प्रभाव dangerouslySetInnerHTMLसमान है - डोम नोड इंजेक्शन एचटीएमएल के साथ अद्यतन करेगा।

हालाँकि , जब आप इसका उपयोग करते हैं तो पर्दे के पीछे dangerouslySetInnerHTMLरिएक्ट से पता चलता है कि उस घटक के अंदर का HTML ऐसा कुछ नहीं है जिसकी उसे परवाह है।

क्योंकि रिएक्ट एक वर्चुअल डोम का उपयोग करता है, जब यह वास्तविक डोम के खिलाफ अंतर की तुलना करने के लिए जाता है, यह सीधे उस नोड के बच्चों की जांच को बायपास कर सकता है क्योंकि यह जानता है कि HTML किसी अन्य स्रोत से आ रहा है । इसलिए प्रदर्शन लाभ है।

इससे भी महत्वपूर्ण बात , यदि आप बस उपयोग करते हैं innerHTML, तो रिएक्ट के पास डोम नोड को संशोधित करने का कोई तरीका नहीं है। अगली बार जब renderफ़ंक्शन को कॉल किया जाता है, तो प्रतिक्रिया उस सामग्री को अधिलेखित कर देगी जिसे मैन्युअल रूप से उस इंजेक्शन के साथ इंजेक्ट किया गया था जो यह सोचता है कि डोम नोड की सही स्थिति होनी चाहिए।

componentDidUpdateसामग्री को हमेशा सुनिश्चित करने के लिए उपयोग करने के लिए आपका समाधान सिंक में है मेरा मानना ​​है कि काम करेगा लेकिन प्रत्येक रेंडर के दौरान एक फ्लैश हो सकता है।


11
मैंने SVG को इनलाइन करने और उपयोग करने के बीच का अंतर दिखाने के लिए एक छोटा, गैर-वैज्ञानिक पूर्ण परीक्षण लिखा है dangerouslySetInnerHTML: webpackbin.com/bins/-KepHa-AMxQgGxOUnAac - भीतरी HTML विधि को देखते हुए लगभग दोगुना तेज़ होता है (वेबपैकिन में कंसोल देखें)
जोश

4
यह सच है और भविष्यवाणी करना आसान है। चूंकि भीतर HTML एक देशी विधि है जो SVG कोड को बिना कुछ सोचे समझे सीधे DOM पर बांध देती है। दूसरी तरफ, खतरनाक तरीके से SETInnerHTML रीऐक्ट से आया तरीका है कि SVG कोड को रिएक्ट कंपोनेंट के बच्चों को वर्चुअल DOM में डालने और फिर DOM को रेंडर करने से पहले पार्स किया जाना चाहिए।
2020

3

खतरनाक तरीके से सेट करें आंतरिक HTML के अनुसार ,

innerHTMLएक क्रॉस-साइट स्क्रिप्टिंग (XSS) हमले के लिए कैन का अनुचित उपयोग आपको खोल सकता है । प्रदर्शन के लिए उपयोगकर्ता इनपुट को सैनिटाइज़ करना बेहद त्रुटिपूर्ण है, और इंटरनेट पर वेब भेद्यता के प्रमुख कारणों में से एक को ठीक से साफ करने में विफलता है।

हमारा डिजाइन दर्शन यह है कि चीजों को सुरक्षित बनाने के लिए "आसान" होना चाहिए, और डेवलपर्स को "असुरक्षित" संचालन करते समय स्पष्ट रूप से अपने इरादे को स्पष्ट करना चाहिए। प्रोप नाम dangerouslySetInnerHTMLजानबूझकर भयावह चुना जाता है, और सैनिटाइज्ड डेटा को इंगित करने के लिए प्रोप वैल्यू (स्ट्रिंग के बजाय एक ऑब्जेक्ट) का उपयोग किया जा सकता है।

सुरक्षा के प्रभाव को पूरी तरह से समझने और डेटा को ठीक से __htmlसाफ करने के बाद, केवल कुंजी और मूल्य के रूप में आपके स्वच्छता डेटा वाले एक नए ऑब्जेक्ट का निर्माण करें। यहाँ JSX सिंटैक्स का उपयोग करके एक उदाहरण दिया गया है:

function createMarkup() {
    return {
       __html: 'First &middot; Second'    };
 }; 

<div dangerouslySetInnerHTML={createMarkup()} /> 

नीचे दिए गए लिंक का उपयोग करके इसके बारे में और पढ़ें:

दस्तावेज़ीकरण : प्रतिक्रिया DOM तत्वों - खतरनाक तरीके से InnerHTML


1
इस सवाल का जवाब नहीं है।
क्वेंटिन

2

के आधार पर ( खतरनाक रूप से InSHTML )।

यह एक प्रोप है जो वास्तव में आप क्या चाहते हैं। हालांकि वे इसे यह बताने के लिए नाम देते हैं कि इसका उपयोग सावधानी से किया जाना चाहिए


1
डॉक्स के अनुसार ऐसा लगता है कि यह एकमात्र कारण है, अभी भी भ्रमित है
mkb
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.