Element: setHTML() 方法
Element 介面的 setHTML() 方法提供了一種 XSS 安全的方法,用於解析和清理 HTML 字串並將其轉換為 DocumentFragment,然後作為元素子樹插入到 DOM 中。
語法
setHTML(input)
setHTML(input, options)
引數
input-
定義要清理並注入到元素中的 HTML 字串。
options可選-
一個包含以下可選引數的 options 物件
sanitizer-
一個
Sanitizer或SanitizerConfig物件,用於定義輸入中允許或刪除的元素,或者字串"default"表示預設配置。請注意,如果配置要重複使用,通常Sanitizer比SanitizerConfig更高效。如果未指定,則使用預設的 Sanitizer 配置。
返回值
無 (undefined)。
異常
TypeError-
如果
options.sanitizer傳遞了以下內容,則丟擲此錯誤- 非規範化的
SanitizerConfig(包含“允許”和“移除”配置設定)。 - 不具有值
"default"的字串。 - 不是
Sanitizer、SanitizerConfig或字串的值。
- 非規範化的
描述
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 字串的一些方法。
// 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> 元素用於注入字串。
<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 不安全的。我們還定義了重新載入按鈕的處理程式。
// 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() 建構函式示例中準確檢視刪除了哪些元素。
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> 也將被刪除!
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 |
瀏覽器相容性
載入中…