【问题标题】:Access parent URL from iframe从 iframe 访问父 URL
【发布时间】:2011-03-26 02:27:08
【问题描述】:

好的,我有一个页面,在这个页面上我有一个 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 时,我不断收到相同的访问被拒绝错误。所以看起来即使是子域也算作跨站点脚本,这是正确的,还是我做错了什么?

【问题讨论】:

  • 你能把它传入框架 URL 吗?如<iframe src="url?parent=parent-url"></iframe>

标签: javascript iframe cross-domain


【解决方案1】:

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

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

注意:

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

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

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

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

【讨论】:

  • 或者,更简洁一点:var url = (parent !== window) ? document.referrer : document.location;
  • 请注意,如果容器位于您的本地主机上(或更一般地说,如果此页面未由 Web 服务器打开)或由 file:// 调用,则它不起作用。跨度>
  • 需要注意的是,这可以用Referer-Policy header 来解决。
  • 这似乎不适用于 Edge 浏览器 - 引荐来源网址将是一个空字符串。stackoverflow.com/questions/24169219/…
  • @thekingoftruth 更简洁:var url = (self===top) ? document.URL : document.referrer; (两个变化:(1)使用肯定而不是否定检查;(2)document.location是一个对象,所以你需要使用document.location.hrefdocument.URL).
【解决方案2】:

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

在你的 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 相结合可以完成工作。
  • 这是一个绝妙的建议。对于那些正在编写父 html iframe 代码的人来说,这将买单。我们在像素软件中使用了非常相似的东西。
  • 谢谢!!这是一种有效的变通方法,仍然遵守跨站点规则。
  • 但是你会在服务器端重写html中的所有url吗?因为否则当用户单击 iFrame 中的链接时,它仍然无法访问。
  • @Roel 您可以在服务器时间编写它们(本质上,“硬编码”此答案),或者您可以在 javascript 中执行此答案,例如在页面加载后它会注入所需的 iframe .
【解决方案3】:

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

var currentUrl = document.referrer;

而且 - 这里有主网址!

【讨论】:

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

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

【讨论】:

  • 在对 Chrome 进行更改之后,这现在是许多浏览器的正确答案。
  • 不是完整的网址。仅域
  • document.location.ancestorOrigins 为我返回 undefined
  • 关于浏览器支持,具体来说,截至 2020 年 7 月,由于隐私问题,Firefox 尚不支持祖先起源。 Bugzilla 功能请求和讨论:bugzilla.mozilla.org/show_bug.cgi?id=1085214。浏览器支持:caniuse.com/#search=ancestorOrigins
【解决方案5】:

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

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

【讨论】:

  • 您可以在两者之间进行交互。但是您必须在父框架和 iframe 上添加以下脚本:
【解决方案6】:

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

父框架和 iframe 都需要将它们的 document.domain 设置为它们之间的共同点。

www.foo.mydomain.comapi.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

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

【讨论】:

  • 请接受这个答案,因为这是可能的,而且这个答案会出现在 Google 搜索中。
【解决方案7】:

试试看:

document.referrer

当您更改您在 iframe 中时,您的主机是“推荐人”。

【讨论】:

  • 今天,在 Chrome 中,这不会返回完整的 URL。当example.com?abc=123 加载 iframe,并且您在 iframe 上运行 document.referrer 时,它只会提供 example.com 并剥离 ?abc=123 部分。
【解决方案8】:

我遇到了这个问题。如果在 iframe 中首次加载页面时使用 php 之类的语言,请抓取 $_SERVER['HTTP_REFFERER'] 并将其设置为会话变量。

这样,当页面在 iframe 中加载时,您就知道加载它的页面的完整父 url 和查询字符串。使用跨浏览器安全性,如果您使用不同的域,则依赖 window.parent 有点令人头疼。

【讨论】:

    【解决方案9】:

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

    【讨论】:

      【解决方案10】:
      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 之外,那么你在父框架上运行脚本,你不需要检查任何东西。
      【解决方案11】:

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

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

      【讨论】:

        【解决方案12】:

        PHP $_SERVER['HTTP_REFFERER'] 的问题在于它提供了将您带到父页面的页面的完全限定页面 url。这与父页面本身不同。更糟糕的是,有时没有http_referer,因为人输入了父页面的url。因此,如果我从 yahoo.com 访问您的父页面,那么 yahoo.com 将成为 http_referer,而不是您的页面。

        【讨论】:

          【解决方案13】:

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

          【讨论】:

            【解决方案14】:

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

            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 上运行。

            【讨论】:

              【解决方案15】:

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

              选项

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

              不起作用的事情

              • window.parent.location.href。如果父子节点在不同的域,这个api会被现代浏览器屏蔽(见here),会报错。

              推荐

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

              【讨论】:

                【解决方案16】:

                这对我访问 iframe src url 很有用。

                window.document.URL
                

                【讨论】:

                  【解决方案17】:

                  我知道他已经很老了,但这让我大吃一惊,没有人建议只将 cookie 从一个域传递到另一个域。当您使用子域时,您只需将 cookie 设置为 url .basedomain.com 即可将基域中的 cookie 共享到所有子域

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

                  【讨论】:

                    【解决方案18】:

                    获取所有父 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。
                    猜你喜欢
                    • 1970-01-01
                    • 2011-11-26
                    • 2010-10-30
                    • 2013-05-07
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2012-04-05
                    • 2011-07-08
                    相关资源
                    最近更新 更多