从iframe访问父网址

chr*_*war 169 javascript iframe cross-domain

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

我已经搜索过,我知道如果我的iframe页面位于不同的域上,这是不可能的,因为这是跨站点脚本.但是我读过的每个地方都说如果iframe页面和父页面在同一个域中,那么如果我这样做,它应该可以工作:

parent.document.location
Run Code Online (Sandbox Code Playgroud)
parent.window.document.location
Run Code Online (Sandbox Code Playgroud)
parent.window.location
Run Code Online (Sandbox Code Playgroud)
parent.document.location.href
Run Code Online (Sandbox Code Playgroud)

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

不管怎么说,这就是问题所在.我的iframe与主页面位于同一个域中,但它不在同一个SUB域中.所以我举个例子

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

然后我的iframe网址是

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

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

小智 330

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

var url = (window.location != window.parent.location)
            ? document.referrer
            : document.location.href;
Run Code Online (Sandbox Code Playgroud)

注意:

window.parent.location被允许; 它避免了OP中的安全性错误,这是由访问href属性引起的:window.parent.location.href导致"阻止带有原始的框架......"

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

  • 容器iframe @ Domain 1
  • 将子iframe发送到域2
  • 但在孩子的iframe ...域2重定向到域3(即进行身份验证,也许SAML),然后域3引导至域2(通过表单提交,即(),一个标准的SAML技术)
  • 对于子iframe,document.referrer将是域3,而不是包含域1

document.location指"位置对象,其中包含有关文档URL的信息"; 可能是当前文档,即iframe当前打开.当window.location === window.parent.location,那么iframe的href为含母公司href.

  • 应该注意的是,这可以通过[`Referer-Policy`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy)标题来解决. (5认同)
  • 或者,更紧凑:`var url =(parent!== window)?document.referrer:document.location;` (2认同)
  • 请注意,如果容器位于您的本地主机上(或更普遍地说,如果该页面未由Web服务器打开)或由file://调用,则该容器不起作用。 (2认同)
  • 这似乎不适用于Edge浏览器 - 引用者将是一个空字符串.. /sf/ask/1691845361/读内包括的iframe (2认同)
  • @thekingoftruth 更简洁:`var url = (self===top) ? document.URL : document.referrer;`(两个变化:(1)使用肯定检查而不是否定检查;(2)`document.location`是一个对象,所以你需要使用`document.location.href`或`document .URL`)。 (2认同)

小智 48

我刚刚发现这个问题的解决方法非常简单,但我还没有找到任何提及它的讨论.它确实需要控制父帧.

在你的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>
Run Code Online (Sandbox Code Playgroud)

然后,找到一个javascript url解析函数,解析url字符串以获取你所追求的url变量,在这种情况下它是"url".

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

  • 这是一个很棒的建议.对于那些正在编写父html iframe代码的人来说,这将是一笔费用.我们在像素软件中使用了非常相似的东西. (2认同)

Par*_*Par 30

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

var currentUrl = document.referrer;
Run Code Online (Sandbox Code Playgroud)

而且 - 这里你有主要的网址!


Dan*_*ert 19

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

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

  • 这是如何选择的答案?下面对可能的解决方案有更好的描述. (7认同)
  • 你可以在2.之间进行交互.但你必须在父和iframe上添加以下脚本:<script> document.domain ="mydomain.com"; </ script> (4认同)

小智 18

对于同一域和不同子域的页面,您可以document.domain通过javascript 设置该属性.

父框架和iframe都需要将其document.domain设置为它们之间通用的内容.

也就是说 www.foo.mydomain.com,api.foo.mydomain.com每个人都可以使用foo.mydomain.com或只是mydomain.com兼容(不com,出于安全原因,你不能将它们都设置为......)

另外,请注意document.domain是一条单行道.请考虑按顺序运行以下三个语句:

// assume we're starting at www.foo.mydomain.com
document.domain = "foo.mydomain.com" // works
document.domain = "mydomain.com" // works
document.domain = "foo.mydomain.com" // throws a security exception
Run Code Online (Sandbox Code Playgroud)

现代浏览器也可以使用window.postMessage来交换原点,但它在IE6中不起作用. https://developer.mozilla.org/en/DOM/window.postMessage

  • 请接受此作为答案,既然这是可能的,并且这个答案即将出现在Google搜索中. (3认同)

J S*_*ott 16

这个问题有很多答案,但就支持或可靠性而言,没有一个答案绝对是最好的。

选项

  • window.location.ancestorOrigins[0]将获取父 url,但此 api 仅适用于 chromium 浏览器(请参阅支持)。这还支持嵌套 iframe,其中最底部的子级可以访问每个父级 iframe 的 url。
  • document.referrer是最常见的答案,但并不总是可靠

不起作用的事情

  • window.parent.location.href。如果父级和子级位于不同的域中,则该 api 会被现代浏览器阻止(请参阅此处),并会抛出错误。

推荐

如果支持,我更喜欢window.location.ancestorOrigins[0]document.referrer可以工作,但不太可靠,使其成为我的后备选择。如果您确实使用文档引荐来源网址,请尝试在导航或重定向之前在第一个框架页面加载时调用它,以获取父地址。


小智 14

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

  • 关于浏览器支持,具体而言,截至 2020 年 7 月,出于隐私问题,Firefox 尚不支持祖先起源。Bugzilla 功能请求和讨论:https://bugzilla.mozilla.org/show_bug.cgi?id=1085214。浏览器支持:https://caniuse.com/#search=ancestorOrigins (4认同)
  • 但不是完整的网址。仅域 (3认同)
  • `document.location.ancestorOrigins` 为我返回 `undefined` (2认同)

小智 6

Try it:

document.referrer
Run Code Online (Sandbox Code Playgroud)

When you change you are in a iframe your host is "referrer".

  • 如今,在 Chrome 中,这不会返回完整的 URL。当“example.com?abc=123”加载 iframe 并在 iframe 上运行“document.referrer”时,它只提供“example.com”并删除“?abc=123”部分。 (7认同)