setHTMLUnsafe は HTML 文字列を要素に挿入するメソッドです。名前に「Unsafe」とあるとおり、サニタイズ処理を行わずに HTML をそのまま解釈します。
基本的な使い方
const div = document.getElementById('container') div.setHTMLUnsafe('<b>太字</b><script>alert("実行される")</script>')
innerHTML と同様に、渡された文字列は HTML として解釈されます。<script> タグも実行されるため、信頼できない入力を渡すと XSS 脆弱性につながります。
innerHTML との違い
setHTMLUnsafe は Declarative Shadow DOM を含む HTML 文字列を処理できます。
const html = ` <div> <template shadowrootmode="open"> <style>p { color: red; }</style> <p>Shadow DOM 内のコンテンツ</p> </template> </div> ` document.body.setHTMLUnsafe(html) // → Shadow DOM が正しく構築される document.body.innerHTML = html // → template 要素がそのまま残り、Shadow DOM は構築されない
innerHTML は <template shadowrootmode="..."> を通常の template 要素として扱いますが、setHTMLUnsafe は Declarative Shadow DOM として解釈し、Shadow Root を構築します。
setHTML との関係
setHTML はサニタイズ処理を行う安全なメソッドです。setHTMLUnsafe はその「安全装置を外した」バージョンという位置づけです。
const dirty = '<img src=x onerror=alert(1)><b>太字</b>' // setHTML: 危険な要素を除去 div.setHTML(dirty) // → <b>太字</b> のみ挿入 // setHTMLUnsafe: そのまま挿入 div.setHTMLUnsafe(dirty) // → img タグも挿入され、onerror が発火する可能性あり
parseHTMLUnsafe
静的メソッド Document.parseHTMLUnsafe を使うと、HTML 文字列から Document オブジェクトを生成できます。
const doc = Document.parseHTMLUnsafe(` <!DOCTYPE html> <html> <head><title>Test</title></head> <body><p>内容</p></body> </html> `) doc.querySelector('p').textContent // → '内容'
こちらも Declarative Shadow DOM を含む HTML を正しく解釈します。
使用場面
setHTMLUnsafe は信頼できるソースからの HTML を扱う場合に限定して使います。サーバーサイドレンダリングで生成した Declarative Shadow DOM を含む HTML を挿入する場合などが典型的なユースケースです。ユーザー入力を含む文字列には決して使わないでください。