从iframe访问父网址


187

好的,我上有一个页面,在此页面上有一个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网址是

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

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


您可以在框架网址中传递它吗?例如<iframe src="url?parent=parent-url"></iframe>
Biagio Arobba '16

Answers:


21

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

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


1
好吧,那就吹了。但是至少我知道我不会发疯:(嗯,计划B。谢谢。(非常抱歉没有将我的东西放入标签中,感谢您的编辑)
chronofwar 2010年

9
所选答案如何?下面对可能的解决方案进行了更好的描述。
Anoyz 2014年

1
同意!下面以80票的答案更好。该答案在html规范中。
Ligemer 2014年

4
您可以在2之间进行交互。但是您必须在父级和iframe上都添加以下脚本:<script> document.domain =“ mydomain.com”; </ script>
乔治

2
“请参阅其他答案以获取更多详细信息。” 哈哈就像:我没有任何解决方案,请参见其他答案,但也接受我的答案。
Milad

370

是的,如果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导致“使用原点阻止帧...”

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

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

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


1
@jepser,这是因为您的iframe位于该iframe中。您将永远无法访问中间带有该框架的顶部框架。在许多级别上,嵌套的跨域iframe是错误的。但是如果您将其设置document.domain在顶部框架和最里面的框架上,则可能可以解决该问题。也许。
gcb

2
或者,稍微紧凑一点:var url = (parent !== window) ? document.referrer : document.location;
thekingoftruth 2014年

2
请注意,如果容器位于您的本地主机上(或更普遍地说,如果该页面未由Web服务器打开)或由file://调用,则该容器不起作用。
Guillaume Renoult

5
应该注意的是,可以用Referer-Policy头来克服这个问题。
Dan Atkinson

2
这似乎并没有工作,边浏览器-指引者将是一个空字符串.. stackoverflow.com/questions/24169219/...
达维德奥拉齐奥Montersino

51

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

在您的iFrame中,说您想要此iframe:src =“ http://www.example.com/mypage.php”

好吧,不是使用HTML来指定iframe,而是使用JavaScript来为iframe构建HTML,“在构建时”通过javascript获取父网址,并将其作为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”。

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


该答案与stackoverflow.com/a/7739035/216084结合在一起即可完成工作。

2
这是一个很棒的建议。对于那些正在编写父html iframe代码的人来说,这将是行之有效的。我们在像素软件中使用了非常相似的东西。
Ligemer 2014年

谢谢!!这是一种有效的变通办法,仍然遵守跨站点规则。
theUtherSide

但是,您是否在服务器上的html中重写了所有URL?因为否则,当用户单击iFrame中的链接时,仍将无法访问该链接。
Roel

@Roel您可以在服务器时全部编写它们(本质上是“硬编码”此答案),也可以在javascript中完成此答案,例如在页面加载后注入所需的iframe。
rogerdpack

34

如果您的iframe来自另一个域(跨域),则只需使用以下命令:

var currentUrl = document.referrer;

-在这里,您有了主网址!


在我看来,这是行不通的,因为我认为iFrame本身是动态生成的或有其他欺骗性。我没有得到我期望的答案。
Muskie 2013年

这应该适用于所有浏览器。除非在较新的浏览器中发送沙箱参数,否则我怀疑是这种情况。不管跨域,这都可以工作。
gcb

如果iframe中的页面通过javascript(例如window.location.reload(true))重新加载了自身,则无法再使用了。那么引荐来源网址是iframe本身的网址。

20

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

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

即, www.foo.mydomain.com并且api.foo.mydomain.com每个都可以使用foo.mydomain.commydomain.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

现代的浏览器也可以使用window.postMessage跨源对话,但在IE6中将无法使用。 https://developer.mozilla.org/en/DOM/window.postMessage


3
既然这是可能的,并且此答案已经出现在Google搜索中,请接受此作为答案。
Metagrapher

17

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


在对Chrome进行更改之后,现在这已成为许多浏览器的正确答案。
Dan Atkinson

不是完整的网址。只有网域
TheMaster '19

document.location.ancestorOrigins返回undefined给我
Miguel Mota

关于浏览器支持,特别是从2020年7月开始,由于隐私方面的考虑,尚未在Firefox中支持ancestorOrigins。Bugzilla功能请求和讨论:bugzilla.mozilla.org/show_bug.cgi?id=1085214。浏览器支持:caniuse.com/#search=ancestorOrigins
colin moock


2

我对此有疑问。如果您的页面首次加载到iframe抓取中时使用了php之类的语言$_SERVER['HTTP_REFFERER'],并将其设置为会话变量。

这样,当网页在iframe中加载时,您就知道加载该网页的完整父网址和查询字符串。有了跨浏览器的安全性,如果您使用不同的域,那么在window.parent上指望是一件令人头疼的事。


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

我发现上面的示例以前建议在iframe中执行脚本时起作用,但是在iframe之外执行脚本时它没有检索url,因此需要进行一些调整:

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

2
如果您位于iframe之外,那么您正在父框架上运行脚本,则无需检查任何内容。
Art3mix

1

我无法获得以前的解决方案,但是我发现,如果我将iframe scr设置为例如,http:otherdomain.com/page.htm?from=thisdomain.com/thisfolder那么我可以thisdomain.com/thisfolder使用以下javascript 在iframe提取中:

var myString = document.location.toString();
var mySplitResult = myString.split("=");
fromString = mySplitResult[1];

1

PHP $ _SERVER ['HTTP_REFFERER']的问题在于,它提供了将您带到父页面的页面的标准页面URL。这与父页面本身不同。更糟糕的是,有时没有http_referer,因为此人在父页面的url中键入内容。因此,如果我从yahoo.com转到您的父页面,则yahoo.com将成为http_referer,而不是您的页面。


1

我发现在$_SERVER['HTTP_REFERER']无法正常工作的情况下(我正在浏览Safari)$_SERVER['REDIRECT_SCRIPT_URI']是一种有用的备份。


0

在chrome中,可以使用location.ancestorOrigins它将返回所有父URL


0

我知道他已经很老了,但我不敢建议只将Cookie从一个域传递到另一个域。在使用子域时,只需将cookie设置为url,就可以将基本域的cookie共享给所有子域。.basedomain.com

然后,您可以通过cookie共享所需的任何数据。


-1

这对我来说可以访问iframe src网址。

window.document.URL

-4

获取所有父级Iframe函数和HTML

var parent = $(window.frameElement).parent();
        //alert(parent+"TESTING");
        var parentElement=window.frameElement.parentElement.parentElement.parentElement.parentElement;
        var Ifram=parentElement.children;      
        var GetUframClass=Ifram[9].ownerDocument.activeElement.className;
        var Decision_URLLl=parentElement.ownerDocument.activeElement.contentDocument.URL;

我不认为您可以为那些不使用jQuery的人扩展这个答案(我应该指出,由于jQuery在过去几年中变得越来越不必要,这一数字正在增加)。至少,我建议明确说明此答案取决于jQuery,而OP完全没有提到jQuery。
Carnix
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.