警告
正如我们在 2022年1月份宣布的,我们将在 Chrome 115 中弃用
document.domain设置器。如果您的网站依赖于通过document.domain来放宽 同源策略,您需要立即采取行动。继续阅读了解为什么会有这个改变,或者跳到你可以实施的 备选方案。
#发生了什么,以及为什么?
从 Chrome 115 开始,网站将无法设置 document.domain:Chrome 将使 document.domain 不可变。要进行跨源通信,您需要使用其他方法,比如 postMessage() 或 Channel Messaging API。
请注意,此更改将逐步推出。
我们希望其他浏览器最终也会弃用和删除此功能。请查看 浏览器兼容性 部分以获取详细信息。
#为什么要使 document.domain 不可变?
document.domain 旨在获取或设置源的主机名。许多网站设置 document.domain 以允许在 同站点跨源 页面之间进行通信。
虽然这是一种方便的技术,但它会引入安全风险,因为它 放宽了同源策略。关于 document.domain 的安全问题已导致规范发生了变化,用户要避免使用它。
详细信息:为什么要使 document.domain 不可变?
如何使用
document.domain许多网站设置
document.domain以允许同站点但跨源页面之间的通信。同站点但跨源站点具有相同的 eTLD+1,但不同的子域。
以下是迄今为止如何使用
document.domain:假设
https://parent.example.com上的页面嵌入了来自https://video.example.com的 iframe 页面。这些页面具有相同的 eTLD+1 (example.com),但不同的子域。当这两个页面的document.domain都设置为'example.com'时,浏览器会将这两个源视为同源。为
https://parent.example.com设置document.domain:// 确认 "parent.example.com" 的当前来源 console.log(document.domain); // 设置 document.domain document.domain = 'example.com'; console.log(document.domain);为
https://video.example.com设置document.domain:// 确认 "video.example.com" 的当前来源 console.log(document.domain); // 设置 document.domain document.domain = 'example.com'; console.log(document.domain);现在,您可以在
https://parent.example.com上针对https://video.example.com创建跨源 DOM 操作。网站设置
document.domain以使同站点文档更容易通信。由于此更改放宽了同源策略,因此父页面可以访问 iframe 的文档并遍历 DOM 树,反之亦然。这是一种方便的技术,但它会引入安全风险。
document.domain的安全问题
document.domain的安全问题已导致规范发生变化,警告用户避免使用它。例如,当两个页面设置
document.domain时,它们可以假装自己是同源的。当这些页面使用具有不同子域的共享托管服务时,这一点尤其关键。设置document.domain可以打开访问由同一服务托管的所有其他站点的权限,这使攻击者更容易访问您的站点。这是可能的,因为document.domain忽略了域名的端口号部分。要了解有关设置
document.domain的安全影响的更多信息,请阅读 MDN 上的“Document.domain”页面。
#浏览器兼容性
- HTML 规范 指出,这个功能应该被删除。
- Mozilla 认为默认禁用
document.domain是值得原型化的。 - WebKit 表示他们对弃用
document.domain设置器持有中等的积极态度。 - 与其他浏览器供应商的讨论
- WHATWG / HTML 工作组 Pull Request (待实验体验)
#如何知道我的网站是否会受到影响?
如果您的网站受到此更改的影响,Chrome 会在 DevTools Issues 面板中发出警告 - 这个警告已经在 2022 年加入了。
请注意 DevTools 右上角的黄色标志。
您还可以通过 LightHouse 弃用 API 审核 运行您的网站,以查找所有预定从 Chrome 中删除的 API。
如果您已设置报告 API,则 Chrome 已向您发送了弃用报告,以通知您即将弃用。了解有关如何使用报告 API 的更多信息,包括使用现有报告收集服务或构建自己的内部解决方案。
#如何查看此更改的效果?
该更改将逐步推出,从 Chrome 115 开始。即使该更改尚未在您的 Chrome 浏览器中推出,您也可以按以下方式打开它以查看其效果:
- 打开
chrome://flags/#origin-agent-cluster-default - 选择 启用。
- 重新启动 Chrome。
#我可以使用哪些备选方案?
最好的选择是根本不修改 document.domain,例如通过在同一源上托管页面和所有组成帧来实现。这适用于所有版本的所有浏览器。但这可能需要对应用程序进行大量的重新工作,因此值得看一下继续支持跨源访问的备选方案。
#使用 postMessage() 或 Channel Messaging API 代替 document.domain
在大多数的用例中,跨源的 postMessage() 或 Channel Messaging API 可以替代 document.domain。
在以下示例中:
https://parent.example.com在 iframe 中请求https://video.example.com以通过postMessage()发送消息来操作 DOM。https://video.example.com一旦收到消息就立即操作 DOM,并向父级通知成功。https://parent.example.com确认成功。
在 https://parent.example.com 上:
// Send a message to <https://video.example.com>
iframe.postMessage('Request DOM manipulation', '<https://video.example.com>');
// Receive messages
iframe.addEventListener('message', (event) => {
// Reject all messages except ones from <https://video.example.com>
if (event.origin !== '<https://video.example.com>') return;
// Filter success messages
if (event.data === 'succeeded') {
// DOM manipulation is succeeded
}
});
在 https://video.example.com 上:
// Receive messages
window.addEventListener('message', (event) => {
// Reject all messages except ones from <https://parent.example.com>
if (event.origin !== '<https://parent.example.com>') return;
// Do a DOM manipulation on <https://video.example.com>.
// Send a success message to <https://parent.example.com>
event.source.postMessage('succeeded', event.origin);
});
试试看,看看它如何工作。如果您有特定的要求,不能使用 postMessage() 或 Channel Messaging API,请通过 Twitter via @ChromiumDev 或在 Stack Overflow 上使用 a document.domain tag 来让我们知道。
#作为最后的选择,通过发送 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,即使它默认情况下变为不可变。
所有其他需要该行为的文档也将需要发送 Origin-Agent-Cluster(请注意,如果只有一个文档设置它,则 document.domain 没有作用)。
#为企业政策配置 OriginAgentClusterDefaultEnabled
可选的,您的管理员可以将 OriginAgentClusterDefaultEnabled 策略配置为 false,以使 Chrome 实例中的 document.domain 可以被默认设置。要了解更多,请阅读 Chrome 企业政策列表和管理 | 文档。
#资源
[Document.domain- Web APIs | MDN](developer.mozilla.org/docs/Web/AP…)- Origin Isolation and Deprecating
document.domain - Deprecating
document.domain. · Issue #564 · w3ctag/design-reviews
#鸣谢
Photo by Finan Akbar on Unsplash。