it-swarm.com.de

<iframe> übergeordnetes DOM mit Javascript-Zugriff über mehrere Domains hinweg?

Ich kontrolliere den Inhalt eines Iframes, der in eine Seite einer anderen Domain eingebettet ist. Kann Javascript in meinem iframe Änderungen am DOM der Eltern vornehmen?

Zum Beispiel möchte ich, dass mein iframed-Skript dem übergeordneten DOM eine Reihe von HTML-Elementen hinzufügt. Das scheint ein ziemlich großer Auftrag zu sein - Gedanken?

Edit: Es gibt eine Technik namens " Fragment ID Messaging ", die eine Möglichkeit zur Kommunikation zwischen domänenübergreifenden Iframes darstellen könnte.

Edit: Auch Firefox 3.5, Opera, Chrome (etc) scheinen die html5 "postMessage" -API zu übernehmen, die eine sichere domänenübergreifende Datenübertragung zwischen Frames, Iframes und Popups ermöglicht. Es funktioniert wie ein Ereignissystem. IE8 unterstützt diese Funktion anscheinend, was vielleicht ein wenig überraschend ist.

Zusammenfassung: Nein, Sie können das DOM einer Seite nicht direkt von einer anderen Domain aus aufrufen/bearbeiten. Aber Sie können kommunizieren damit, und es kann zusammenarbeiten, um die gewünschten Änderungen vorzunehmen.

16
aaaidan

Ich hasse es, es zu sagen, aber ich bin zu 99% sicher, dass dies aus Sicherheitsgründen nicht direkt geschieht.

Sie können es ausprobieren hier .

bhh

19
Andy Gaskell

Es ist möglich.

Sie haben zu Recht postMessage in Ihren Bearbeitungen erwähnt. Für diejenigen, die suchen, gibt es eine großartige, rückwärtskompatible, nur mit Javascript ausgestattete Methode, um über Domains hinweg zu kommunizieren. Kurzer, einfacher Code. Perfekte Lösung? Solange Sie Änderungen am übergeordneten Element und am untergeordneten Objekt anfordern können:

http://www.onlineaspect.com/2010/01/15/backwards-compatible-postmessage/

11
Kyle

Ja, du kannst. 
Sie können window.postMessage implementieren, um über Iframes und/oder Windows-Domänen hinweg zu kommunizieren.
Aber Sie müssen es asynchron machen. 
Wenn Sie es synchron benötigen, müssen Sie Wrapper für diese asynchronen Methoden implementieren.

<!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>

Hier würden Sie das Kind so ändern, dass es Postnachrichten an das Elternteil sendet. Z. in child.htm tun Sie

window.parent.postMessage("alert(document.location.href); document.location.href = 'http://www.google.com/ncr'", "*");

und in Parent tun Sie (in receiveMessage) eval(evt.data); Da eval nicht unsicher ist, würden Sie stattdessen ein Enum übergeben und die entsprechende Funktion aufrufen, die Sie auf der übergeordneten Seite einfügen müssen.

5
Stefan Steiger

Bei AJAX könnte der Server den Header Access-Control-Allow-Origin: * zurückgeben, um den domänenübergreifenden Zugriff zu ermöglichen. Vielleicht funktioniert es auch für IFRAMEs.

0
user836773

Ich denke, Sie werden auf Sicherheitsprobleme stoßen, ohne einen Proxy zu verwenden. Proxies können sehr nützlich sein. Sie können eine davon ausprobieren: 

(1) a PHP -basierter Proxy (Achtung, es gibt viele Anzeigen zwischen nützlichen Links)

(2) ein Apache .htaccess-Proxy - erstellen Sie einfach ein Unterverzeichnis proxy in Ihrer Domäne und fügen Sie dort eine .htaccess-Datei mit folgenden Dateien ein:

RewriteEngine on
RewriteRule ^(.*)$ http://picasaweb.google.com/$1 [P,L] 

Setzen Sie den anderen Domainnamen anstelle von picasaweb.google.com

Ich persönlich bevorzuge den Apache-Proxy

0
warpech