web-dev-qa-db-fra.com

<iframe> javascript accès DOM DOM à travers les domaines?

Je contrôle le contenu d'un iframe intégré à une page d'un autre domaine. Existe-t-il un moyen pour javascript dans mon iframe d'apporter des modifications au DOM du parent?

Par exemple, j'aimerais que mon script iframed ajoute de nombreux éléments HTML au DOM parent. Cela semble être une tâche difficile - des pensées?

Edit: Il existe une technique appelée " Fragment ID Messaging " qui pourrait être un moyen de communiquer entre iframes interdomaines.

Edit: De plus, Firefox 3.5, Opera, Chrome (etc.) semblent adopter l’application html5 "postMessage" api , qui permet une transmission sécurisée de données entre domaines entre images, iframes et popups. Cela fonctionne comme un système d'événements. IE8 supporte apparemment cette fonctionnalité, ce qui est peut-être un peu surprenant.

Résumé: Non, vous ne pouvez pas accéder/modifier directement le DOM d'une page d'un autre domaine. Mais vous pouvez communiquer avec lui et il peut coopérer pour apporter les modifications souhaitées.

16
aaaidan

Je suis désolé de le dire mais je suis presque à 99% sûr que cela ne se produira pas directement pour des raisons de sécurité.

Vous pouvez l'essayer ici .

bhh

19
Andy Gaskell

C'est possible.

Vous avez eu raison de mentionner postMessage dans vos modifications. Pour ceux qui cherchent, il existe un excellent moyen de communiquer à travers les domaines, compatible uniquement avec les versions antérieures. Code court et facile aussi. Solution parfaite? Tant que vous pouvez demander des modifications au parent et à l'enfant:

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

11
Kyle

Oui, vous pouvez. 
Vous pouvez implémenter window.postMessage pour communiquer entre iframes et/ou fenêtres entre domaines.
Mais vous devez le faire de manière asynchrone. 
Si vous en avez besoin de manière synchrone, vous devez implémenter des wrappers autour de ces méthodes asynchrones.

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

Ici, vous pouvez modifier l’enfant pour qu’il envoie des messages post-messages au parent. dans child.htm, vous faites

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

et dans parent, vous faites (dans receiveMessage) eval(evt.data); Cela ne signifie pas qu'utiliser eval n'est pas sûr, vous transmettez donc une énumération et appelez la fonction correspondante que vous devez placer sur la page parent.

5
Stefan Steiger

Pour AJAX, le serveur peut renvoyer l'en-tête Access-Control-Allow-Origin: * pour autoriser l'accès entre domaines. Peut-être que cela fonctionne aussi pour les IFRAME.

0
user836773

Je suppose que vous rencontrerez des problèmes de sécurité sans utiliser de proxy. Les procurations peuvent être très utiles. Vous pouvez essayer l'un de ceux-ci: 

(1) un proxy basé sur PHP (soyez prudent, car il y a beaucoup d'annonces entre les liens utiles)

(2) un proxy Apache .htaccess - créez simplement un sous-répertoire proxy dans votre domaine et y placez un fichier .htaccess contenant

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

Mettez l'autre nom de domaine à la place de picasaweb.google.com

Personnellement, je préfère utiliser le proxy Apache

0
warpech