从 iframe 访问父 URL

IT技术 javascript iframe cross-domain
2021-01-16 11:07:49

好的,我有一个页面,在这个页面上我有一个 iframe。我需要做的是在iframe页面上,找出主页的URL是什么。

我四处搜索,我知道如果我的 iframe 页面位于不同的域中,这是不可能的,因为这是跨站点脚本。但我读过的所有地方都说,如果 iframe 页面与父页面在同一个域中,如果我这样做,它应该可以工作:

parent.document.location
parent.window.document.location
parent.window.location
parent.document.location.href

...或其他类似的组合,因为似乎有多种方法可以获得相同的信息。

无论如何,问题来了。我的 iframe 与主页在同一个域中,但不在同一个 SUB 域中。所以例如我有

http://www.mysite.com/pageA.html

然后我的 iframe URL 是

http://qa-www.mysite.com/pageB.html

当我尝试从pageB.html(iframe 页面)获取 URL 时,我不断收到相同的访问被拒绝错误。所以似乎子域也算作跨站点脚本,这是正确的,还是我做错了什么?

6个回答

是的,如果 iframe 和主页不在同一个(子)域中,则不允许访问父页面的 URL。但是,如果您只需要主页的 URL(即浏览器 URL),则可以尝试以下操作:

var url = (window.location != window.parent.location)
            ? document.referrer
            : document.location.href;

笔记:

window.parent.location被允许; 它避免了 OP 中由访问href属性引起的安全错误window.parent.location.href导致“Blocked a frame with origin...”

document.referrer指的是“链接到此页面的页面的 URI”。如果某些其他来源决定了位置,这可能不会返回包含文档iframe,例如:

  • 容器 iframe @ 域 1
  • 将子 iframe 发送到域 2
  • 但是在子 iframe 中...域 2 重定向到域 3(即用于身份验证,可能是 SAML),然后域 3 重定向域 2(即通过表单提交(),一种标准的 SAML 技术)
  • 对于子 iframedocument.referrer将是域3,而不是包含域1

document.location指的是“一个 Location 对象,其中包含有关文档 URL 的信息”;大概是当前文档,即当前打开的 iframe。window.location === window.parent.location,那么iframe的href为含母公司href

请注意,如果容器位于您的本地主机上(或更一般地说,如果此页面未由 Web 服务器打开)或由 file:// 调用,则它不起作用。
2021-03-22 11:07:49
应该注意的是,这可以通过Referer-Policy头球来击败
2021-03-28 11:07:49
或者,稍微紧凑一点: var url = (parent !== window) ? document.referrer : document.location;
2021-03-30 11:07:49
这似乎不适用于 Edge 浏览器 - 引用者将是一个空字符串.. stackoverflow.com/questions/24169219/...
2021-03-31 11:07:49
@thekingoftruth 更简洁:(var url = (self===top) ? document.URL : document.referrer;两个变化:(1)使用肯定检查而不是否定检查;(2)document.location是一个对象,所以你需要使用document.location.hrefor document.URL)。
2021-04-05 11:07:49

我刚刚发现了一个解决这个问题的方法,它非常简单,但我还没有在任何地方找到任何提到它的讨论。它确实需要控制父框架。

在你的 iFrame 中,假设你想要这个 iframe: src="http://www.example.com/mypage.php"

好吧,不是使用 HTML 来指定 iframe,而是使用 javascript 为您的 iframe 构建 HTML,通过“构建时”通过 javascript 获取父 url,并将其作为 url GET 参数发送到您的 src 目标的查询字符串中,例如所以:

<script type="text/javascript">
  url = parent.document.URL;
  document.write('<iframe src="http://example.com/mydata/page.php?url=' + url + '"></iframe>');
</script>

然后,为自己找到一个 javascript url 解析函数,该函数解析 url 字符串以获取您要查找的 url 变量,在本例中它是“url”。

我在这里找到了一个很棒的 url 字符串解析器:http : //www.netlobo.com/url_query_string_javascript.html

这个答案结合stackoverflow.com/a/7739035/216084可以完成工作。
2021-03-19 11:07:49
这是一个绝妙的建议。对于那些正在编写父 html iframe 代码的人来说,这将买单。我们在像素软件中使用了非常相似的东西。
2021-03-28 11:07:49
@Roel 您可以在服务器时间编写它们(本质上,“硬编码”此答案),或者您可以在 javascript 中编写此答案,例如在页面加载后它会注入所需的 iframe。
2021-03-31 11:07:49
谢谢!!这是一个仍然尊重跨站点规则的有效解决方法。
2021-04-03 11:07:49
但是您是否在服务器端重写了 html 中的所有 url?因为否则当用户单击 iFrame 中的链接时,它仍然无法访问。
2021-04-10 11:07:49

如果您的 iframe 来自另一个域(跨域),您只需要使用这个:

var currentUrl = document.referrer;

和 - 在这里你有主网址!

这应该适用于所有浏览器。除非在较新的浏览器中发送沙盒参数,但我怀疑是这种情况。无论跨域如何,这都有效。
2021-03-26 11:07:49
如果 iframe 内的页面通过 javascript(例如window.location.reload(true)重新加载,这将不再起作用。那么referrer 就是iframe 本身的URL。
2021-04-01 11:07:49
这在我的情况下不起作用,因为我认为 iFrame 本身是动态生成的,或者做了一些其他的诡计。无论如何,我没有得到我期望的答案。
2021-04-02 11:07:49

以下行将起作用:document.location.ancestorOrigins[0]这一返回祖先域名。

关于浏览器支持,具体而言,截至 2020 年 7 月,由于隐私问题,Firefox 尚不支持祖先起源。Bugzilla 功能请求和讨论:bugzilla.mozilla.org/show_bug.cgi?id=1085214浏览器支持:caniuse.com/#search=ancestorOrigins
2021-03-11 11:07:49
虽然不是完整的网址。只有域
2021-03-18 11:07:49
在对 Chrome 进行更改之后,这现在是许多浏览器的正确答案。
2021-03-22 11:07:49
document.location.ancestorOriginsundefined为我回报
2021-04-06 11:07:49

你是对的。使用 iframe 时,子域仍被视为单独的域。可以使用 传递消息postMessage(...),但有意使其他 JS API 无法访问。

仍然可以根据上下文获取 URL。有关更多详细信息,请参阅其他答案。

您可以在 2 之间进行交互。但是您必须在父框架和 iframe 上添加以下脚本:<script>document.domain="mydomain.com";</script>
2021-03-21 11:07:49