Microsoft Edge 将禁用修改 document.domain

警告

如果网站依赖于通过 document.domain放宽同源策略,则需要执行操作。 继续阅读有关更改原因的详细信息,或转到 备用跨源通信 ,了解实现跨源通信的替代机制。

简介

Document 接口的“域”属性获取或设置当前文档的原点的域部分,由 同一源策略使用。

Microsoft Edge 从 Chromium 继承了此更改。 现在忽略使用 JavaScript 修改 document.domain 属性的尝试。 需要使用替代方法(如 postMessage() 或通道消息 API)进行跨源通信。 此更改在 Edge 119 及更高版本中进行。

或者,如果网站依赖同源策略放宽来 document.domain 正常运行,则网站可能会发送标头 Origin-Agent-Cluster: ?0 ;此标头必须从需要放宽的所有其他文档发送。

注意

document.domain 如果只有一个文档设置它,则不起作用。

为什么使不 document.domain 可变?

某些网站设置为 document.domain 允许“同一网站但跨源”页面之间的通信。 通过设置 document.domain ,同一站点文档可以更轻松地进行通信。 由于此更改 放宽了同源策略,因此父页可以访问同一站点 iframe 的文档并遍历 DOM 树,反之亦然。

重要提示

同一站点但跨源站点具有相同的 eTLD+1 ,但子域不同。

假设上的 https://parent.example.com 页面嵌入了 中的 https://video.example.comiframe 页面。 这些页面具有相同的 eTLD+1 (example.com 具有不同子域的) 。 当两个页面 document.domain 设置为 'example.com'时,浏览器会将这两个页面视为同一源。

此方法很方便:但这会带来安全风险。

安全问题 document.domain

围绕 document.domain 的安全问题导致了规范的更改,该规范向开发人员发出有关此担忧的警告,并告知他们尽可能避免使用它。 目前 与其他浏览器供应商 的讨论正朝着相同的方向发展。

以下示例演示了攻击者如何滥用 document.domain

请考虑为每位客户提供唯一子域的共享托管服务。 如果开发人员在其页面中设置 document.domain ,则攻击者从其他子域提供的页面可以设置相同的值并修改受害者页面的内容。

同样,请考虑一个共享托管服务,该服务为每个客户使用不同的端口为页面提供服务。 如果开发人员在其页面中设置 document.domain ,则攻击者从其他端口提供的页面可以设置相同的值并修改受害者页面的内容。 这种攻击是可能的,因为 document.domain 忽略源的端口号组件。

注意

若要了解有关设置 document.domain的安全影响的详细信息,请阅读 MDN 上的 Document.domain 一文

如何知道我的网站是否受到影响?

如果网站受到此更改的影响,Microsoft Edge 会在“DevTools 问题”面板中显示警告。 以下屏幕截图显示了此警告的示例。

修改 document.domain 时的警告。

如果设置了报告终结点,则还会向你发送弃用报告。 详细了解 如何将报表 API 与现有报表收集服务配合使用,或通过构建自己的报表解决方案。

提示

可以通过 LightHouse 弃用的 API 审核 运行站点,以查找计划从 Microsoft Edge 中删除的所有 API。

备用跨域通信

目前,你有两个选项可以替换 document.domain 你的网站。 在大多数用例中,跨源 postMessage () 通道消息 API 可以替换 document.domain

以下列表显示了开发人员需要使用 postMessage() 的步骤,而不是 document.domain 用于跨源 DOM 操作。

  1. https://parent.example.com 通过 postMessage() 将消息发送到 iframe,其中包含 https://video.example.com 要求其修改其自己的 DOM。
  2. https://video.example.com 操作其 DOM,并使用 postMessage 来通知父级其成功。
  3. https://parent.example.com 确认成功。

对于 上的 https://parent.example.com步骤 1:


// Configure a handler to receive messages from the subframe.
iframe.addEventListener('message', (event) => { 

// Reject all messages except from https://video.example.com 
  if (event.origin !== 'https://video.example.com') return;
  
  // Filter success messages 
    if (event.data === 'succeeded') { 

    // DOM manipulation is succeeded 

  } 

}); 

// Send a message to the subframe at https://video.example.com

iframe.postMessage('Request DOM manipulation', 'https://video.example.com'); 

对于上的 https://video.example.com步骤 2:


// Configure a handler to receive messages from the parent frame.
window.addEventListener('message', (event) => {
 
  // Reject all messages except ones from https://parent.example.com 
  
  if (event.origin !== 'https://parent.example.com') return;
  
  // Perform requested DOM manipulation on https://video.example.com.
  
  if (event.data === "showTheButton") {
     document.getElementById('btnContinue').style.visibility = 'visible';
     // Send a success message back to the parent.

     event.source.postMessage('succeeded', event.origin); 
  }
}); 

发送 Origin-Agent-Cluster: ?0 标头作为最后的手段

如果有充分的理由继续设置 document.domain,则可以在目标文档上发送 Origin-Agent-Cluster: ?0 响应标头。

Origin-Agent-Cluster: ?0 

标头 Origin-Agent-Cluster 指示浏览器文档是否应由源密钥代理群集处理。 若要详细了解 Origin-Agent-Cluster,请阅读 使用 Origin-Agent-Cluster 标头请求性能隔离

发送此页眉时,即使文档默认变为不可变,也可以继续设置 document.domain

浏览器兼容性

为了提高浏览器兼容性,以下组织支持弃用 document.domain

其他资源

内容许可证

注意

本页面的某些部分是根据 Chromium.org 创建和共享的作品所做的修改,并根据 Creative Commons Attribution 4.0 国际许可证中所述的条款进行使用。 可在此处找到原始页面。

Creative Commons 许可证
本作品根据 Creative Commons Attribution 4.0 International License 获得许可。