JavaScript document.domain Uncaught DOMException: Blocked a frame with origin
Posted
技术标签:
【中文标题】JavaScript document.domain Uncaught DOMException: Blocked a frame with origin【英文标题】: 【发布时间】:2019-07-19 15:33:24 【问题描述】:当我在测试 SOP 时,我遇到了这种情况,两个文档与我预期的同一个域有关系,当我尝试获取位置时它会引发错误。
重现问题:
-
打开https://www.google.com
来自控制台
let opened = window.open("https://www.google.com")
在同一窗口中执行opened.location.toString()
,这将返回正确的位置
从第二个选项卡的控制台执行document.domain = "www.google.com"
从第一个标签执行opened.location.toString()
,你会得到一个错误
Uncaught DOMException: Blocked a frame with origin "https://www.google.com" from accessing a cross-origin frame.
at <anonymous>:1:12
谁能解释这种奇怪的行为?
【问题讨论】:
【参考方案1】:此错误不是错误。同源策略是一种安全机制,可确保窗口对象只能访问它们被授权获取的信息。就您而言,这包括访问opened.location
。
创建后,两个选项卡具有相同的来源,这允许第一个选项卡访问opened.location
。但在致电document.domain='www.google.com'
之后,他们不再这样做了。
“什么?但在两个选项卡中,window.location.origin
是相同的”
是的,但它有点复杂。来源由方案/主机/端口元组定义,有关更多详细信息,请参阅@TheUnknown 的答案。 scheme和host一直保持不变,就是window.location.origin
字符串中包含的那个。
需要知道的是,任何对document.domain
的调用,包括document.domain = document.domain
,都会导致端口号被null
覆盖,从而导致两个选项卡的差异。来源,并阻止他们相互交流opened.location
之类的信息,从而导致错误。
从 MDN 的guide on same-origin policy 中提取的信息
【讨论】:
在这两种情况下,端口都是空的——在设置它之前和之后。仅当明确在域中时才设置端口 我不同意。在两个标签中运行document.domain = document.domain
允许第一个仍然访问opened
的字段
来自您自己的链接,“如果协议、端口(如果指定),则两个 URL 具有相同的来源”
两个地方都没有指定端口,所以限制不适用
链接的 MDN 特别地 详细说明了设置 domain.domain
会导致权限错误的方式和原因。它还解释了浏览器单独检查端口号,这可能解释了这种行为。【参考方案2】:
首先,我建议您阅读Same-origin Policy。
同源策略是一种关键的安全机制,可以限制 从一个来源加载的文档或脚本如何与 来自另一个来源的资源。它有助于隔离潜在的恶意 文档,减少可能的攻击媒介。
如果 protocol、端口(如果指定)和主机对于两者来说相同,则两个 URL 具有相同的来源。您可能会看到这被称为“方案/主机/端口元组”,或者只是“元组”。 (“元组”是一组项目,它们共同构成一个整体——双/三/四/五/等的通用形式。)
在这种特殊情况下,您使用 HTTPS 协议打开一个窗口,但是当您设置域时,协议将更改为 HTTP,见下图:
根据1,如果协议不同,则违反原则,因此您会收到错误
Uncaught DOMException: Blocked a frame with origin "https://www.google.com" 从访问 cross-origin 框架。
cross-origin是这里的关键字。
另外,请查看SecurityError: Blocked a frame with origin from accessing a cross-origin frame 了解更多详情。
【讨论】:
嗯,不相信。您的回答肯定是一个很好的输入,但是在使用 example.com 而不是 google.com 时会出现同样的错误 @NinoFiliu 你能详细说明一下吗?是的,它不会工作,因为两者都是不同的域。 鼠标悬停在document.location
更改前后是一样的;他们都是http://www.google.com
@TheUknown 如果您在 OP 的问题中将 every https://www.google.com
替换为 http://example.com
,错误仍然显示
我已经找到了答案,我目前正在编辑!仅供参考【参考方案3】:
尽管如此,这将有点缺乏信息性(仅陈述事实):
更改窗口 B 中的domain
后,窗口 B 停止将窗口 A 记为 opener
。
由于窗口 A 不再被视为窗口 B 的打开者,因此禁止访问。
这让我想到,改变 document.domain
被认为是潜在的不安全,并通过孤立子窗口来“惩罚”。
【讨论】:
以上是关于JavaScript document.domain Uncaught DOMException: Blocked a frame with origin的主要内容,如果未能解决你的问题,请参考以下文章
javascript JavaScript isset()等效: - JavaScript