如何使用 Javascript 从 iframe 实现跨域 URL 访问?

IT技术 javascript iframe cross-domain
2021-01-24 20:52:09

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

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

我尝试的是使用以下代码:

window.parent.location.href()

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

6个回答

您可以尝试检查引用者,如果您是 iframe,它应该是父站点

你可以这样做:

var href = document.referrer;
这仅在您第一次打开 iframe 时有效。如果您在 iframe 内导航,则前一页将成为引用者。
2021-04-10 20:52:09

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

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


同源策略上的维基百科页面带来有关安全措施一些信息:

简而言之,该策略允许在来自同一站点的页面上运行的脚本在没有特定限制的情况下访问彼此的方法和属性——但阻止跨不同站点的页面访问大多数方法和属性。

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

您可以实现window.postMessage跨域跨 iframes/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>

儿童.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) 中的子页面。
2021-03-21 20:52:09
@lmiguelmh:正确 - 如果是这样,那将是一个安全错误,浏览器需要修复。在这种情况下,您可以做的是 A)将子页面放在 https 中,B)从 iframe 到 https 页面的表单发布,在 https 页面上,您有网络套接字,如果表单发布到达服务器。或者以 x 秒的间隔轮询是否有新数据到达。如果您为帖子分配了 guid,则孩子可以对 https 页面(应该被允许)进行 JSONP 轮询,通过 guid 询问答案 - 轮询直到得到它。不知道在那个案例中是否可以使用网络套接字。
2021-04-05 20:52:09

您有几个选择:

  1. 在包含页面和iframe同一事物中将域向下(请参阅 document.domain)范围那么它们将不受“同源”约束的约束。

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

这里的好文章: 使用 iframe 进行跨域通信

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

document.domain = document.domain;

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