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

瀏覽器相容性

另見