Element: insertAdjacentHTML() 方法

Baseline 已广泛支持

此功能已成熟,可跨多种设备和浏览器版本工作。它自 ⁨2018 年 4 月⁩ 起已在所有浏览器中可用。

警告: 此方法将其输入解析为 HTML 或 XML,并将结果写入 DOM。像这样的 API 被称为注入槽,如果输入最初来自攻击者,则可能成为跨站脚本 (XSS) 攻击的载体。

您可以通过分配TrustedHTML 对象而不是字符串,并使用require-trusted-types-for CSP 指令强制执行受信任的类型来降低风险。这确保了输入通过一个转换函数,该函数有机会清理输入,以移除潜在危险的标记,例如<script> 元素和事件处理程序属性。

Element 接口的 insertAdjacentHTML() 方法将指定的输入解析为 HTML 或 XML,并将生成的节点插入到 DOM 树中的指定位置。

语法

js
insertAdjacentHTML(position, input)

参数

position

一个字符串,表示相对于元素的位置。必须是以下字符串之一:

"beforebegin"

在元素之前。仅当元素在 DOM 树中且具有父元素时有效。

"afterbegin"

就在元素内部,在它的第一个子元素之前。

"beforeend"

就在元素内部,在它的最后一个子元素之后。

"afterend"

在元素之后。仅当元素在 DOM 树中且具有父元素时有效。

input

一个TrustedHTML 实例或字符串,定义要解析的 HTML 或 XML。

返回值

无(undefined)。

异常

此方法可能会抛出以下类型之一的DOMException

NoModificationAllowedError DOMException

如果 position"beforebegin""afterend",并且该元素没有父元素或者其父元素是 Document 对象,则抛出此错误。

SyntaxError DOMException

在以下情况下抛出

  • position 不是列出的四个值之一。
  • 输入是格式不正确的 XML。
TypeError

如果在可信类型CSP 强制执行且未定义默认策略时将属性设置为字符串,则抛出此错误。

描述

insertAdjacentHTML() 方法不会重新解析它所作用的元素,因此它不会破坏该元素内部的现有元素。这避免了额外的序列化步骤,使其比直接操作innerHTML 快得多。

其中 <p> 是元素,我们可以将插入内容“foo”的可能位置可视化如下:

html
<!-- 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

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

css
code {
  color: red;
}

JavaScript

可信类型尚未在所有浏览器中受支持,因此我们首先定义可信类型小型填充。这可以作为可信类型 JavaScript API 的透明替代品。

js
if (typeof trustedTypes === "undefined")
  trustedTypes = { createPolicy: (n, rules) => rules };

接下来,我们定义一个名为 some-content-policy 的策略,用于从输入中创建TrustedHTML 对象(我们也应该使用 CSP 强制执行 some-content-policy)。此代码实现了一个无操作策略,以使此示例在没有第三方依赖的情况下也能工作。您自己的应用程序代码应该使用第三方库(例如“DOMPurify”库)来从不可信输入中返回清理后的内容。

js
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 的元素所选位置的相对位置。

js
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

浏览器兼容性

另见