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 |
浏览器兼容性
加载中…