HTMLScriptElement: text 属性

Baseline 广泛可用 *

此特性已相当成熟,可在许多设备和浏览器版本上使用。自 ⁨2015 年 7 月⁩以来,各浏览器均已提供此特性。

* 此特性的某些部分可能存在不同级别的支持。

警告:此属性表示 script 元素的文本内容,根据 script 的类型,它可能是可执行的。像这样的 API 被称为注入点,并可能成为跨站脚本 (XSS) 攻击的载体。

您可以通过始终分配 TrustedScript 对象而不是字符串,并强制执行受信任的类型来减轻这种风险。有关更多信息,请参阅安全注意事项

HTMLScriptElement 接口的 text 属性表示 script 元素的内联文本内容。它的作用与textContent 属性相同。

获取该属性会返回一个包含元素文本的字符串。

设置该属性可以接受 TrustedScript 对象或字符串。

描述

HTMLScriptElement 接口的 text 属性表示 <script> 元素内的文本内容。

对于可执行脚本type,例如模块或经典脚本,此文本是内联可执行代码。对于其他类型,它可能代表导入映射、推测规则或其他类型的数据块。

请注意,如果设置了 src 属性,则会忽略 text 属性的内容。

text vs textContent vs innerText

HTMLScriptElementtexttextContent 属性是等效的:都可以用字符串或 TrustedScript 类型设置,并且都返回一个表示 script 元素内容的字符串。主要区别在于 textContent 也定义在 Node 上,并且可以与其他元素一起使用来设置它们的字符串内容。

innerText 通常以与其它方法相同的方式设置和执行文本,但可能返回略微不同的值。原因是此属性旨在获取 HTML 标记字符串的渲染文本。设置值时,文本被视为文本节点,它会像可见文本一样规范化字符串(折叠空格并将 \n 转换为换行符)。这不会改变文本的执行,但会改变存储和返回的文本。

安全注意事项

text 属性是跨站脚本 (XSS) 攻击的潜在载体,其中可能会执行用户提供的潜在不安全字符串。例如,以下示例假定 scriptElement 是一个可执行的 <script> 元素,并且 untrustedCode 是由用户提供的。

js
const untrustedCode = "alert('Potentially evil code!');";
scriptElement.text = untrustedCode; // shows the alert

您可以通过始终分配 TrustedScript 对象而不是字符串,并使用 require-trusted-types-for CSP 指令强制执行受信任类型来缓解这些问题。这可以确保输入通过转换函数,该函数有机会在文本被注入之前对其进行清理或拒绝。

转换函数的行为将取决于需要用户提供的脚本的具体用例。如果可能,您应该将允许的脚本锁定为正好是您信任运行的代码。如果不可能,您可能允许或阻止在提供的字符串中使用某些函数。

示例

使用 TrustedScript

为了缓解 XSS 风险,我们应始终将 TrustedScript 实例分配给 text 属性。

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

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

接下来,我们创建一个 TrustedTypePolicy,它定义了一个 createScript() 方法,用于将输入字符串转换为 TrustedScript 实例。在本例中,我们只允许我们需要的脚本。

js
const policy = trustedTypes.createPolicy("inline-script-policy", {
  createScript(input) {
    // Here specify what scripts are safe to allow
    if (input === "const num = 10;\nconsole.log(num)") {
      return input; // allow this exact script
    }
    throw new TypeError(`Untrusted script blocked: ${input}`);
  },
});

接下来,我们将创建 script 元素,并将值赋给该元素,并获取该元素的句柄。

html
<script id="el" type="text/javascript"></script>
js
// Get the script element we're injecting the code into
const el = document.getElementById("el");

然后,我们使用 policy 对象从潜在不安全的输入字符串创建 trustedScript 对象,并将结果分配给该元素。

js
// The potentially malicious string
const untrustedScriptOne = "const num = 10;\nconsole.log(num)";

// Create a TrustedScript instance using the policy
const trustedScript = policy.createScript(untrustedScriptOne);

// Inject the TrustedScript (which contains a trusted string)
el.text = trustedScript;

比较 texttextContent

在此示例中,我们将通过将代码字符串分配给元素的 text 属性和 textContent 属性来设置 script 元素的值,并读取结果以显示结果是等效的。

请注意,在这种情况下,我们没有使用策略来创建受信任的脚本(为简洁起见,我们假设提供的字符串是受信任的)。

js
// Set the text property
el.text = "const num = 10;\nconsole.log(num)";
console.log(el.text); // Output: "const num = 10;\nconsole.log(num);"
console.log(el.textContent); // Output: "const num = 10;\nconsole.log(num);"

// Set the textContent property
el.textContent = "console.log(10);";
console.log(el.text); // Output: "console.log(10);"
console.log(el.textContent); // Output: "console.log(10);"

规范

规范
HTML
# dom-script-text-dev

浏览器兼容性

另见