Element: setHTML() 方法

可用性有限

此特性不是基線特性,因為它在一些最廣泛使用的瀏覽器中不起作用。

實驗性: 這是一項實驗性技術
在生產中使用此技術之前,請仔細檢查瀏覽器相容性表格

Element 介面的 setHTML() 方法提供了一種 XSS 安全的方法,用於解析和清理 HTML 字串並將其轉換為 DocumentFragment,然後作為元素子樹插入到 DOM 中。

語法

js
setHTML(input)
setHTML(input, options)

引數

input

定義要清理並注入到元素中的 HTML 字串。

options 可選

一個包含以下可選引數的 options 物件

sanitizer

一個 SanitizerSanitizerConfig 物件,用於定義輸入中允許或刪除的元素,或者字串 "default" 表示預設配置。請注意,如果配置要重複使用,通常 SanitizerSanitizerConfig 更高效。如果未指定,則使用預設的 Sanitizer 配置。

返回值

無 (undefined)。

異常

TypeError

如果 options.sanitizer 傳遞了以下內容,則丟擲此錯誤

描述

setHTML() 方法提供了一種 XSS 安全的方法,用於解析和清理 HTML 字串並將其轉換為 DocumentFragment,然後作為元素子樹插入到 DOM 中。

setHTML() 會刪除 HTML 輸入字串中在當前元素上下文中無效的任何元素,例如 <table> 外部的 <col> 元素。然後,它會刪除 Sanitizer 配置不允許的任何 HTML 實體,並進一步刪除任何 XSS 不安全的元素或屬性——無論 Sanitizer 配置是否允許它們。

如果在 options.sanitizer 引數中沒有指定 Sanitizer 配置,則 setHTML() 將使用預設的 Sanitizer 配置。此配置允許所有被認為是 XSS 安全的元素和屬性,從而禁止被認為不安全的實體。可以指定自定義 Sanitizer 或 Sanitizer 配置來選擇允許或刪除哪些元素、屬性和註釋。請注意,即使 Sanitizer 配置允許不安全選項,在使用此方法時它們仍將被刪除(該方法隱式呼叫 Sanitizer.removeUnsafe())。

對於將不受信任的 HTML 字串插入到元素中,應使用 setHTML() 而非 Element.innerHTML。除非有允許不安全元素和屬性的特殊需求,否則也應使用 setHTML() 而非 Element.setHTMLUnsafe()

請注意,由於此方法始終對 XSS 不安全實體的輸入字串進行清理,因此它不受 Trusted Types API 的保護或驗證。

示例

基本用法

此示例展示了使用 setHTML() 清理和注入 HTML 字串的一些方法。

js
// Define unsanitized string of HTML
const unsanitizedString = "abc <script>alert(1)<" + "/script> def";
// Get the target Element with id "target"
const target = document.getElementById("target");

// setHTML() with default sanitizer
target.setHTML(unsanitizedString);

// Define custom Sanitizer and use in setHTML()
// This allows only elements: div, p, button (script is unsafe and will be removed)
const sanitizer1 = new Sanitizer({
  elements: ["div", "p", "button", "script"],
});
target.setHTML(unsanitizedString, { sanitizer: sanitizer1 });

// Define custom SanitizerConfig within setHTML()
// This removes elements div, p, button, script, and any other unsafe elements/attributes
target.setHTML(unsanitizedString, {
  sanitizer: { removeElements: ["div", "p", "button", "script"] },
});

setHTML() 即時示例

此示例透過不同的 Sanitizer 呼叫該方法時提供了“即時”演示。程式碼定義了按鈕,您可以單擊它們分別使用預設和自定義 Sanitizer 清理和注入 HTML 字串。原始字串和清理後的 HTML 都已記錄,以便您可以檢查每種情況下的結果。

HTML

HTML 定義了兩個 <button> 元素用於應用不同的 Sanitizer,另一個按鈕用於重置示例,以及一個 <div> 元素用於注入字串。

html
<button id="buttonDefault" type="button">Default</button>
<button id="buttonAllowScript" type="button">allowScript</button>

<button id="reload" type="button">Reload</button>
<div id="target">Original content of target element</div>

JavaScript

首先,我們定義要清理的字串,所有情況下都相同。它包含 <script> 元素和 onclick 處理程式,兩者都被認為是 XSS 不安全的。我們還定義了重新載入按鈕的處理程式。

js
// Define unsafe string of HTML
const unsanitizedString = `
  <div>
    <p>This is a paragraph. <button onclick="alert('You clicked the button!')">Click me</button></p>
    <script src="path/to/a/module.js" type="module"><script>
  </div>
`;

const reload = document.querySelector("#reload");
reload.addEventListener("click", () => document.location.reload());

接下來,我們定義使用預設 Sanitizer 設定 HTML 的按鈕的單擊處理程式。這應該在插入 HTML 字串之前剝離所有不安全的實體。請注意,您可以在 Sanitizer() 建構函式示例中準確檢視刪除了哪些元素。

js
const defaultSanitizerButton = document.querySelector("#buttonDefault");
defaultSanitizerButton.addEventListener("click", () => {
  // Set the content of the element using the default sanitizer
  target.setHTML(unsanitizedString);

  // Log HTML before sanitization and after being injected
  logElement.textContent =
    "Default sanitizer: remove script element and onclick attribute\n\n";
  log(`\nunsanitized: ${unsanitizedString}`);
  log(`\nsanitized: ${target.innerHTML}`);
});

下一個單擊處理程式使用自定義 Sanitizer 設定目標 HTML,該 Sanitizer 僅允許 <div><p><script> 元素。請注意,因為我們使用的是 setHTML 方法,所以 <script> 也將被刪除!

js
const allowScriptButton = document.querySelector("#buttonAllowScript");
allowScriptButton.addEventListener("click", () => {
  // Set the content of the element using a custom sanitizer
  const sanitizer1 = new Sanitizer({
    elements: ["div", "p", "script"],
  });
  target.setHTML(unsanitizedString, { sanitizer: sanitizer1 });

  // Log HTML before sanitization and after being injected
  logElement.textContent =
    "Sanitizer: {elements: ['div', 'p', 'script']}\n Script removed even though allowed\n";
  log(`\nunsanitized: ${unsanitizedString}`);
  log(`\nsanitized: ${target.innerHTML}`);
});

結果

單擊“Default”和“allowScript”按鈕,分別檢視預設 Sanitizer 和自定義 Sanitizer 的效果。請注意,在這兩種情況下,即使 Sanitizer 明確允許,<script> 元素和 onclick 處理程式都將被刪除。

規範

規範
HTML Sanitizer API
# dom-element-sethtml

瀏覽器相容性

另見