文档:writeln() 方法

已弃用:此特性不再推荐。虽然某些浏览器可能仍然支持它,但它可能已经从相关的网络标准中删除,可能正在删除过程中,或者可能仅为兼容性目的而保留。请避免使用它,如果可能,请更新现有代码;请参阅本页底部的兼容性表格以指导您的决策。请注意,此特性可能随时停止工作。

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

您可以通过始终传递 TrustedHTML 对象而不是字符串并 强制执行可信类型 来缓解此风险。有关更多信息,请参阅 安全注意事项

Document 接口的 writeln() 方法将一个或多个 TrustedHTML 或字符串参数中的文本写入到由 document.open() 打开的文档流中,并在其后添加一个换行符。

语法

js
writeln(markup)
writeln(markup, markup2)
writeln(markup, markup2, /* …, */ markupN)

参数

markup, …, markupN

TrustedHTML 或字符串对象,包含要写入文档的文本。

返回值

无(undefined)。

异常

InvalidStateError DOMException

此方法是在 XML 文档上调用的,或者在解析器当前正在执行自定义元素构造函数时调用的。

TypeError

强制执行可信类型(Trusted Types)没有定义默认策略来创建 TrustedHTML 对象时,字符串被作为其中一个参数传递。

描述

此方法与 document.write() 基本相同,但会添加一个换行符(链接主题中的信息也适用于此方法)。此换行符仅在注入到显示换行符的元素内部时才可见。document.write() 中的其他信息也适用于此方法。

安全注意事项

此方法是跨站脚本(XSS)攻击的一个潜在载体,其中用户提供的潜在不安全的字符串在未首先进行清理的情况下被注入到 DOM 中。尽管此方法在某些浏览器中可能会阻止<script>元素在注入时执行(有关 Chrome 的信息,请参阅Intervening against document.write()),但它易受到攻击者以多种其他方式精心构造 HTML 以运行恶意 JavaScript 的攻击。

您可以通过始终传递 TrustedHTML 对象而不是字符串,并使用 require-trusted-types-for CSP 指令强制执行可信类型来缓解这些问题。这确保了输入通过转换函数传递,该函数有机会在注入之前清理输入,以移除潜在危险的标记(例如<script>元素和事件处理程序属性)。

示例

写入 TrustedHTML

此示例使用 Trusted Types API 在将 HTML 字符串写入文档之前对其进行清理。您应始终使用可信类型来将不受信任的字符串传递给不安全的 API。

该示例最初显示一些默认文本和一个按钮。当点击按钮时,当前文档被打开,一些 HTML 字符串被转换为 TrustedHTML 实例并写入文档,然后文档被关闭。这会替换示例框架中的文档,包括按钮的原始 HTML 和进行更新的 JavaScript!

HTML

html
<p>Some original document content.</p>
<button id="replace" type="button">Replace document content</button>

JavaScript

首先,我们使用 Window.trustedTypes 属性访问全局 TrustedTypePolicyFactory,并使用其 createPolicy() 方法定义一个名为 "docPolicy" 的策略。

新策略定义了一个转换函数 createHTML(),用于创建我们将传递给 writeln() 方法的 TrustedHTML 对象。此方法可以对输入字符串进行任何操作:可信类型 API 只是要求您将输入通过策略转换函数传递,而不是要求转换函数执行任何特定操作。

您可以使用此方法通过移除潜在不安全的功能(例如 <script> 标签或事件处理程序属性)来清理输入。清理很难做到正确,因此此过程通常使用信誉良好的第三方库,例如 DOMPurify

在这里,我们实现了一个基本的“清理器”,它将脚本开始和结束标签中的 < 符号替换为 &lt; 字符。此示例中注入的字符串实际上不包含任何有害元素,因此这纯粹是为了演示。

js
const policy = trustedTypes.createPolicy("docPolicy", {
  createHTML(string) {
    return string
      .replace("<script", "&lt;script")
      .replace("</script", "&lt;/script");
  },
});

然后我们可以对返回的策略使用 TrustedTypePolicy.createHTML() 方法,从我们原始的输入字符串创建 TrustedHTML 对象。当用户点击按钮时,这些对象随后会传递给 writeln() 函数。

js
const replace = document.querySelector("#replace");
const oneInput = "<h1>Out with";
const twoInput = "the old</h1>";
const threeInput = "<pre>in with";
const fourInput = "the new!</pre>";

replace.addEventListener("click", () => {
  document.open();
  document.writeln(policy.createHTML(oneInput));
  document.writeln(policy.createHTML(twoInput), policy.createHTML(threeInput));
  document.writeln(policy.createHTML(fourInput));
  document.close();
});

结果

点击按钮。请注意,每次调用 writeln() 后都会添加一个换行符,但由于 <pre> 元素默认保留空白,因此此换行符仅在该元素内部可见。

规范

规范
HTML
# dom-document-writeln-dev

浏览器兼容性