【问题标题】:How do I implement Cross Domain URL Access from an Iframe using Javascript?如何使用 Javascript 从 iframe 实现跨域 URL 访问?
【发布时间】:2021-09-06 04:34:35
【问题描述】:

我需要从另一个域中的 iframe 访问父域 URL。

例如,“example.com”是我的网站,其中包含来自另一个父域的 iframe,例如“google.com”。在这里,我需要从我的 example.com 访问父域 URL。也就是说,我需要在“example.com”域中获取 URL“google.com”。此外,父域不能硬编码。

我尝试使用以下代码:

window.parent.location.href()

但这会导致访问被拒绝错误。为了实现这一目标,我该如何正确实施?

【问题讨论】:

    标签: javascript iframe cross-domain


    【解决方案1】:

    您可以尝试检查引荐来源网址,如果您是 iframe,则应该是父网站

    你可以这样做:

    var href = document.referrer;
    

    【讨论】:

    • 这仅在您第一次打开 iframe 时有效。如果您在 iframe 中导航,则上一页将成为引荐来源。
    【解决方案2】:

    您可能想看看这些问题/答案;他们可以给你一些关于你的问题的信息:

    简而言之:出于安全原因,无法从另一个域访问 iframe - 这解释了您收到的错误消息。


    维基百科上的Same origin policy 页面提供了有关该安全措施的一些信息:

    简而言之,政策允许 在原始页面上运行的脚本 从同一站点访问每个 其他的方法和属性没有 特定限制——但阻止 访问大多数方法和属性 跨不同网站的页面。

    内容之间的严格分隔 由无关网站提供的必须是 在客户端维护以防止 数据机密性丢失或 完整性。

    【讨论】:

      【解决方案3】:

      您可以实现 window.postMessage 以跨域跨 iframe/windows 进行通信,而不是使用引荐来源网址。
      您发布到 window.parent,然后 parent 返回 URL。
      这可行,但它需要异步通信。
      如果需要同步,则必须围绕异步方法编写同步包装器。

      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta http-equiv="content-type" content="text/html; charset=utf-8" />
          <title></title>
      
          <!--
          <link rel="shortcut icon" href="/favicon.ico">
      
      
          <link rel="start" href="http://benalman.com/" title="Home">
      
          <link rel="stylesheet" type="text/css" href="/code/php/multi_file.php?m=benalman_css">
      
          <script type="text/javascript" src="/js/mt.js"></script>
          -->
          <script type="text/javascript">
              // What browsers support the window.postMessage call now?
              // IE8 does not allow postMessage across windows/tabs
              // FF3+, IE8+, Chrome, Safari(5?), Opera10+
      
              function SendMessage()
              {
                  var win = document.getElementById("ifrmChild").contentWindow;
      
                  // http://robertnyman.com/2010/03/18/postmessage-in-html5-to-send-messages-between-windows-and-iframes/
      
      
                  // http://stackoverflow.com/questions/16072902/dom-exception-12-for-window-postmessage
                  // Specify origin. Should be a domain or a wildcard "*"
      
                  if (win == null || !window['postMessage'])
                      alert("oh crap");
                  else
                      win.postMessage("hello", "*");
                  //alert("lol");
              }
      
      
      
              function ReceiveMessage(evt) {
                  var message;
                  //if (evt.origin !== "http://robertnyman.com")
                  if (false) {
                      message = 'You ("' + evt.origin + '") are not worthy';
                  }
                  else {
                      message = 'I got "' + evt.data + '" from "' + evt.origin + '"';
                  }
      
                  var ta = document.getElementById("taRecvMessage");
                  if (ta == null)
                      alert(message);
                  else
                      document.getElementById("taRecvMessage").innerHTML = message;
      
                  //evt.source.postMessage("thanks, got it ;)", event.origin);
              } // End Function ReceiveMessage
      
      
      
      
              if (!window['postMessage'])
                  alert("oh crap");
              else {
                  if (window.addEventListener) {
                      //alert("standards-compliant");
                      // For standards-compliant web browsers (ie9+)
                      window.addEventListener("message", ReceiveMessage, false);
                  }
                  else {
                      //alert("not standards-compliant (ie8)");
                      window.attachEvent("onmessage", ReceiveMessage);
                  }
              }
          </script>
      
      
      </head>
      <body>
      
          <iframe id="ifrmChild" src="child.htm" frameborder="0" width="500" height="200" ></iframe>
          <br />
      
      
          <input type="button" value="Test" onclick="SendMessage();" />
      
      </body>
      </html>
      

      Child.htm

      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta http-equiv="content-type" content="text/html; charset=utf-8" />
          <title></title>
      
          <!--
          <link rel="shortcut icon" href="/favicon.ico">
      
      
          <link rel="start" href="http://benalman.com/" title="Home">
      
          <link rel="stylesheet" type="text/css" href="/code/php/multi_file.php?m=benalman_css">
      
          <script type="text/javascript" src="/js/mt.js"></script>
          -->
      
          <script type="text/javascript">
              /*
              // Opera 9 supports document.postMessage() 
              // document is wrong
              window.addEventListener("message", function (e) {
                  //document.getElementById("test").textContent = ;
                  alert(
                      e.domain + " said: " + e.data
                      );
              }, false);
              */
      
              // https://developer.mozilla.org/en-US/docs/Web/API/window.postMessage
              // http://ejohn.org/blog/cross-window-messaging/
              // http://benalman.com/projects/jquery-postmessage-plugin/
              // http://benalman.com/code/projects/jquery-postmessage/docs/files/jquery-ba-postmessage-js.html
      
              // .data – A string holding the message passed from the other window.
              // .domain (origin?) – The domain name of the window that sent the message.
              // .uri – The full URI for the window that sent the message.
              // .source – A reference to the window object of the window that sent the message.
              function ReceiveMessage(evt) {
                  var message;
                  //if (evt.origin !== "http://robertnyman.com")
                  if(false)
                  {
                      message = 'You ("' + evt.origin + '") are not worthy';
                  }
                  else
                  {
                      message = 'I got "' + evt.data + '" from "' + evt.origin + '"';
                  }
      
                  //alert(evt.source.location.href)
      
                  var ta = document.getElementById("taRecvMessage");
                  if(ta == null)
                      alert(message);
                  else
                      document.getElementById("taRecvMessage").innerHTML = message;
      
                  // http://javascript.info/tutorial/cross-window-messaging-with-postmessage
                  //evt.source.postMessage("thanks, got it", evt.origin);
                  evt.source.postMessage("thanks, got it", "*");
              } // End Function ReceiveMessage
      
      
      
      
              if (!window['postMessage'])
                  alert("oh crap");
              else {
                  if (window.addEventListener) {
                      //alert("standards-compliant");
                      // For standards-compliant web browsers (ie9+)
                      window.addEventListener("message", ReceiveMessage, false);
                  }
                  else {
                      //alert("not standards-compliant (ie8)");
                      window.attachEvent("onmessage", ReceiveMessage);
                  }
              }
          </script>
      
      
      </head>
      <body style="background-color: gray;">
          <h1>Test</h1>
      
          <textarea id="taRecvMessage" rows="20" cols="20" ></textarea>
      
      </body>
      </html>
      

      【讨论】:

      • 子 iframe 的加载在混合模式环境中不起作用。例如,https 中的主页面和 iframe (http) 中的子页面。
      • @lmiguelmh:正确 - 如果是这样,那将是一个安全错误,浏览器需要修复。在这种情况下您可以做的是 A) 将子页面放在 https 中,B) 从 iframe 到 https 页面的表单发布,在 https 页面上,如果表单发布到达,您有 web-sockets 会收到通知服务器。或者以 x 秒的间隔轮询是否有新数据到达。如果您为帖子分配一个 guid,那么孩子可以 JSONP 轮询 https 页面(应该允许),通过 guid 询问答案 - 轮询直到它得到它。不知道 web-sockets 是否可以在 ThatCase 中使用。
      【解决方案4】:

      你有几个选择:

      1. 将包含页面和iframe 中的域缩小(参见document.domain)范围相同。那么它们就不会受到“同源”约束。

      2. 使用所有 HTML5 浏览器都支持的 postMessage 进行cross-domain 通信。

      【讨论】:

        【解决方案5】:

        好文章在这里: Cross-domain communication with iframes

        你也可以直接在两个框架中设置 document.domain 相同(甚至

        document.domain = document.domain;
        

        代码有意义,因为将端口重置为空),但这个技巧不是通用的。

        【讨论】:

          【解决方案6】:

          试试

          window.frameElement.ownerDocument.domain
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-12-09
            • 2010-11-20
            • 1970-01-01
            • 1970-01-01
            • 2013-03-05
            • 1970-01-01
            相关资源
            最近更新 更多