React.js: innerHTML'yi tehlikeli olarak ayarlama


171

Bir öğenin innerHTML'sinin ayarlanması ile elementin dangerouslySetInnerHTML özelliğinin ayarlanması arasında herhangi bir "sahne arkası" farkı var mı? Basitlik uğruna işleri düzgün bir şekilde sterilize ettiğimi varsayın.

Misal:

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

vs

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

Yukarıdaki örnekten biraz daha karmaşık bir şey yapıyorum, ama genel fikir aynı

Yanıtlar:


237

Evet, bir fark var!

Buna innerHTMLkarşı kullanmanın hemen etkisi dangerouslySetInnerHTMLaynıdır - DOM düğümü, enjekte edilen HTML ile güncellenir.

Bununla birlikte , kullandığınız sahnelerin arkasında dangerouslySetInnerHTMLReact'ın bu bileşenin içindeki HTML'nin önemsediği bir şey olmadığını bilmesini sağlar.

React sanal bir DOM kullandığı için, farkı gerçek DOM ile karşılaştırmaya gittiğinde, bu düğümün alt öğelerini kontrol ederek doğrudan atlayabilir, çünkü HTML'nin başka bir kaynaktan geldiğini bilir . Performans artışı var.

Daha da önemlisi , sadece kullanırsanız innerHTML, React'ın DOM düğümünün değiştirildiğini bilmesinin bir yolu yoktur. renderİşlev bir sonraki çağrıldığında, React , el ile enjekte edilen içeriğin üzerine, bu DOM düğümünün doğru durumunun olması gerektiğini düşündüğü şeyin üzerine yazar .

componentDidUpdateHer zaman içeriğin senkronize olduğundan emin olmak için kullanacağınız çözümün işe yarayacağına inanıyorum, ancak her render sırasında bir flaş olabilir.


11
Bir SVG'yi satırlamak ve kullanmak arasındaki farkı göstermek için küçük, bilimsel olmayan bir mükemmel test yazdımdangerouslySetInnerHTML : webpackbin.com/bins/-KepHa-AMxQgGxOUnAac - innerHTML yöntemini neredeyse iki kat daha hızlı ayarlıyor (webpackbin'deki konsola bakın)
Joscha

4
Bu doğru ve tahmin edilmesi kolay. İnnerHTML, SVG kodunu hiçbir şey düşünmeden doğrudan DOM'a bağlayan yerel bir yöntem olduğundan. Öte yandan, dangerouslySetInnerHTML, React'den gelen ve SVG kodunun React Component alt öğesi olarak sanal DOM'ye yerleştirilmesinden ve daha sonra DOM'a oluşturulmadan önce ayrıştırılması gereken yöntemdir.
Up209d

3

Göre Tehlikeli Seti innerHTML ,

Şunun yanlış kullanımı, siteler arası komut dosyası (XSS) saldırısına innerHTMLkadar sizi açabilir . Görüntüleme için kullanıcı girişini dezenfekte etmek herkesin bildiği gibi hataya açıktır ve düzgün bir şekilde dezenfekte edilmemesi internetteki web güvenlik açıklarının önde gelen nedenlerinden biridir.

Tasarım felsefemiz, işleri güvenli hale getirmenin "kolay" olması ve geliştiricilerin "güvensiz" işlemler gerçekleştirirken niyetlerini açıkça belirtmeleri gerektiğidir. Prop adı dangerouslySetInnerHTMLkasıtlı olarak korkutucu olarak seçilir ve prop değeri (dize yerine bir nesne) sterilize edilmiş verileri belirtmek için kullanılabilir.

Güvenlik sonuçlarını tam olarak anladıktan ve verileri düzgün bir şekilde temizledikten sonra __html, değer olarak yalnızca anahtarı ve sterilize edilmiş verilerinizi içeren yeni bir nesne oluşturun . JSX sözdizimini kullanan bir örnek:

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

<div dangerouslySetInnerHTML={createMarkup()} /> 

Aşağıdaki bağlantıyı kullanarak daha fazla bilgi edinin:

belgeleri : DOM Öğelerini Yanıtla - dangerouslySetInnerHTML .


1
Bu soruya cevap vermiyor.
Quentin

2

( DangerouslySetInnerHTML ) temel alınmıştır.

Tam olarak ne istediğinizi yapan bir pervane. Ancak dikkatle kullanılması gerektiğini belirtmek için adını verdiler


1
dokümanlar göre bu hala karışık olan tek nedeni gibi görünüyor
mkb
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.