从iframe访问父URL

好的,我有一个页面在这个页面上有一个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时,我一直得到相同的访问拒绝错误。因此,即使子域也可以算作跨站脚本,这是正确的,还是我做错了什么?

350459 次浏览

你是正确的。当使用iframe时,子域仍然被认为是单独的域。可以使用postMessage(...)传递消息,但有意使其他JS api不可访问。

还可以根据上下文获取URL。详见其他答案。

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

父帧和iframe都需要设置它们的文档。域是指它们之间共有的东西。

< p >。 www.foo.mydomain.comapi.foo.mydomain.com可以分别使用foo.mydomain.com或仅使用mydomain.com并且相互兼容(不,出于安全原因,不能将它们同时设置为com…)

另外,请注意文档。领域是一条单行道。考虑按顺序运行以下三条语句:

// 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 < / p >

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

在你的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 < / p >

我不能得到以前的解决方案的工作,但我发现,如果我设置iframe scr与例如http:otherdomain.com/page.htm?from=thisdomain.com/thisfolder,然后我可以,在iframe提取thisdomain.com/thisfolder通过使用以下javascript:

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

是的,如果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发送到Domain 2
  • 但是在子iframe中。Domain 2重定向到Domain 3(即用于身份验证,可能是SAML),然后Domain 3将回来定向到Domain 2(即通过表单提交(),一种标准的SAML技术)
  • 对于子iframe, document.referrer将是域3.,而不是包含域1

document.location指的是“一个Location对象,它包含关于文档URL的信息”;大概是当前的文档,即当前打开的iframe。当window.location === window.parent.location时,iframe的href是包含父元素的href相同

我在这方面有问题。如果使用像php这样的语言,当你的页面第一次加载iframe时,抓取$_SERVER['HTTP_REFFERER']并将其设置为会话变量。

这样,当页面在iframe中加载时,您就知道加载它的页面的完整父url和查询字符串。对于跨浏览器的安全性,依赖于窗口有点让人头疼。如果你有不同的域名,父级任何东西。

PHP $_SERVER['HTTP_REFFERER']的问题是它给出了将您带到父页面的页面的完全限定页面url。这和父页面本身不一样。更糟糕的是,有时没有http_referer,因为用户输入了父页面的url。如果我从yahoo.com到你的父页面,yahoo.com就变成http_referer,而不是你的页面。

我发现在$_SERVER['HTTP_REFERER']不起作用的情况下(我在看你,Safari), $_SERVER['REDIRECT_SCRIPT_URI']一直是一个有用的备份。

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

var currentUrl = document.referrer;

这里有主url!

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;

这为我访问iframe src url工作。

window.document.URL

获取所有父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;
在chrome中可以使用location.祖宗起源 它将返回所有父url

document.location.ancestorOrigins[0]这一行返回祖先域名。

我知道他的是超级老,但它让我震惊,没有人建议只是从一个域名传递cookie到另一个域名。当你在使用子域时,你可以将cookie从一个基本域共享到所有子域,只需将cookie设置为url .basedomain.com

然后你可以通过cookies分享你需要的任何数据。

试一试:

document.referrer

当你在iframe中更改时,你的主机是“referrer”。

有一个跨浏览器的脚本获取父源:

private getParentOrigin() {
const locationAreDisctint = (window.location !== window.parent.location);
const parentOrigin = ((locationAreDisctint ? document.referrer : document.location) || "").toString();


if (parentOrigin) {
return new URL(parentOrigin).origin;
}


const currentLocation = document.location;


if (currentLocation.ancestorOrigins && currentLocation.ancestorOrigins.length) {
return currentLocation.ancestorOrigins[0];
}


return "";
}

这段代码,应该在Chrome和Firefox上工作。

这个问题有很多答案,但在支持或可靠性方面,没有一个肯定是最好的。

选项

  • window.location.ancestorOrigins[0]将获得父url,但此api仅适用于铬浏览器(参见支持)。这也支持嵌套的iframe,其中最底部的子可以访问每个父iframe的url。
  • document.referrer是最常见的答案,但并不总是可靠的
    • iframe内的导航将显示最后一页,而不是父帧url
    • 重定向只显示最近的引用者到当前页面
    • 如果页面重新加载自己,那么引用器就变成了页面本身
    • http子http父HTTPS有一个空字符串引用

不管用的东西

  • window.parent.location.href。如果父类和子类在不同的域中,这个api会被现代浏览器阻塞(参见在这里),并抛出一个错误。

建议

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

假设你要告诉父页面如何设置iframe,以便insecurily获得包含路径和URL参数的完整URL,在指定iframe时包括referrerpolicy="unsafe-url":

<iframe src="https://example.com/innersite" referrerpolicy="unsafe-url" title="My Title"></iframe>

然后你可以得到完整的原始URL:

document.referrer

许多其他答案只有当iframe src与父域相同时才有效。

回退:

如果存在安全问题,你可以做一个回退,就像https://stackoverflow.com/a/5697801/1226799说的那样,父类在iframe URL的URL参数中显式地发送它的URL, 但攻击者很容易伪造这一点。

我相信你也可以使用消息传递并检查事件的起源:https://stackoverflow.com/a/61548595/1226799