【问题标题】:JavaScript document.domain Uncaught DOMException: Blocked a frame with originJavaScript document.domain Uncaught DOMException: Blocked a frame with origin
【发布时间】:2019-07-19 15:33:24
【问题描述】:

当我在测试 SOP 时,我遇到了这种情况,两个文档与我预期的同一个域有关系,当我尝试获取位置时它会引发错误。

重现问题:

  1. 打开https://www.google.com
  2. 来自控制台let opened = window.open("https://www.google.com")
  3. 在同一窗口中执行opened.location.toString(),这将返回正确的位置
  4. 从第二个选项卡的控制台执行document.domain = "www.google.com"
  5. 从第一个标签执行opened.location.toString(),你会得到一个错误

    Uncaught DOMException: Blocked a frame with origin "https://www.google.com" from accessing a cross-origin frame.
    at <anonymous>:1:12
    

谁能解释这种奇怪的行为?

【问题讨论】:

    标签: javascript dom same-origin-policy


    【解决方案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 被认为是潜在的不安全,并通过孤立子窗口来“惩罚”。

    【讨论】:

      猜你喜欢
      • 2019-01-19
      • 1970-01-01
      • 1970-01-01
      • 2016-04-15
      • 2018-12-12
      • 1970-01-01
      • 2017-01-13
      • 2020-12-10
      相关资源
      最近更新 更多