Element: insertAdjacentHTML() 方法
警告: 此方法将其输入解析为 HTML 或 XML,并将结果写入 DOM。像这样的 API 被称为注入槽,如果输入最初来自攻击者,则可能成为跨站脚本 (XSS) 攻击的载体。
您可以通过分配TrustedHTML 对象而不是字符串,并使用require-trusted-types-for CSP 指令强制执行受信任的类型来降低风险。这确保了输入通过一个转换函数,该函数有机会清理输入,以移除潜在危险的标记,例如<script> 元素和事件处理程序属性。
Element 接口的 insertAdjacentHTML() 方法将指定的输入解析为 HTML 或 XML,并将生成的节点插入到 DOM 树中的指定位置。
语法
insertAdjacentHTML(position, input)
参数
position-
一个字符串,表示相对于元素的位置。必须是以下字符串之一:
"beforebegin"-
在元素之前。仅当元素在 DOM 树中且具有父元素时有效。
"afterbegin"-
就在元素内部,在它的第一个子元素之前。
"beforeend"-
就在元素内部,在它的最后一个子元素之后。
"afterend"-
在元素之后。仅当元素在 DOM 树中且具有父元素时有效。
input-
一个
TrustedHTML实例或字符串,定义要解析的 HTML 或 XML。
返回值
无(undefined)。
异常
此方法可能会抛出以下类型之一的DOMException:
NoModificationAllowedErrorDOMException-
如果
position是"beforebegin"或"afterend",并且该元素没有父元素或者其父元素是Document对象,则抛出此错误。 SyntaxErrorDOMException-
在以下情况下抛出
position不是列出的四个值之一。- 输入是格式不正确的 XML。
TypeError
描述
insertAdjacentHTML() 方法不会重新解析它所作用的元素,因此它不会破坏该元素内部的现有元素。这避免了额外的序列化步骤,使其比直接操作innerHTML 快得多。
其中 <p> 是元素,我们可以将插入内容“foo”的可能位置可视化如下:
<!-- beforebegin -->
<p>
<!-- afterbegin -->
foo
<!-- beforeend -->
</p>
<!-- afterend -->
该方法不包含对<template> 元素的任何特殊处理。在大多数情况下,开发者应该在模板的content 属性上使用 insertAdjacentHTML(),而不是直接操作模板元素的子节点。
安全注意事项
此方法不执行任何清理,以移除 XSS 不安全的元素(如<script>)或事件处理程序内容属性。
当使用 insertAdjacentHTML() 将 HTML 插入页面时,您应该传递TrustedHTML 对象而不是字符串,并使用require-trusted-types-for CSP 指令强制执行受信任的类型。这确保了输入通过一个转换函数,该函数有机会在注入之前清理输入以移除潜在危险的标记。
当您知道用户提供的内容应该是纯文本时,应使用Element.insertAdjacentText() 方法或Node.textContent。这会将输入作为原始文本插入,而不是将其解析为 HTML。
示例
插入 HTML
此示例演示了四个插入位置。所有插入的文本都加粗,而插入到元素内部的文本则进一步样式化为红色等宽字体(代码)。
HTML
<select id="position">
<option>beforebegin</option>
<option>afterbegin</option>
<option>beforeend</option>
<option>afterend</option>
</select>
<button id="insert">Insert HTML</button>
<button id="reset">Reset</button>
<p>
Some text, with a <code id="subject">code-formatted element</code> inside it.
</p>
CSS
code {
color: red;
}
JavaScript
可信类型尚未在所有浏览器中受支持,因此我们首先定义可信类型小型填充。这可以作为可信类型 JavaScript API 的透明替代品。
if (typeof trustedTypes === "undefined")
trustedTypes = { createPolicy: (n, rules) => rules };
接下来,我们定义一个名为 some-content-policy 的策略,用于从输入中创建TrustedHTML 对象(我们也应该使用 CSP 强制执行 some-content-policy)。此代码实现了一个无操作策略,以使此示例在没有第三方依赖的情况下也能工作。您自己的应用程序代码应该使用第三方库(例如“DOMPurify”库)来从不可信输入中返回清理后的内容。
const policy = trustedTypes.createPolicy("some-content-policy", {
createHTML(input) {
return input; // Do not do this in your own code!
// Instead do something like:
// return DOMPurify.sanitize(input);
},
});
const unsafeText = "<strong>inserted text</strong>";
const trustedHTML = policy.createHTML(unsafeText);
剩余的代码将受信任的 HTML 插入到 ID 为 subject 的元素所选位置的相对位置。
const insert = document.querySelector("#insert");
insert.addEventListener("click", () => {
const subject = document.querySelector("#subject");
const positionSelect = document.querySelector("#position");
subject.insertAdjacentHTML(positionSelect.value, trustedHTML);
});
const reset = document.querySelector("#reset");
reset.addEventListener("click", () => {
document.location.reload();
});
结果
规范
| 规范 |
|---|
| HTML # the-insertadjacenthtml()-method |
浏览器兼容性
加载中…
另见
Element.insertAdjacentElement()Element.insertAdjacentText()XMLSerializer:将 DOM 树序列化为 XML 字符串- Trusted Types API