web-dev-qa-db-fra.com

Comment puis-je implémenter l'accès URL inter-domaines à partir d'un Iframe en utilisant Javascript?

J'ai besoin d'accéder à l'URL du domaine parent à partir de mon Iframe qui se trouve dans un autre domaine.

Par exemple, "example.com" est mon site Web qui possède un Iframe d'un autre domaine parent, tel que "google.com". Ici, je dois accéder à l'URL du domaine parent à partir de mon exemple.com. Autrement dit, je dois obtenir l'URL "google.com" dans mon domaine "example.com". De plus, le domaine parent ne peut pas être codé en dur.

J'ai essayé d'utiliser le code suivant:

window.parent.location.href()

mais cela se traduit par une erreur d'accès refusé. Comment puis-je l'implémenter correctement pour y parvenir?

29
Sri Kumar

Vous pouvez essayer de vérifier le référent, qui devrait être le site parent si vous êtes un iframe

vous pouvez le faire comme ceci:

var href = document.referrer;
34
Yuliy

Vous voudrez peut-être jeter un œil à ces questions/réponses; ils pourraient vous donner quelques informations concernant votre problème:

Pour faire court: il n'est pas possible d'accéder à iframe à partir d'un autre domaine, pour des raisons de sécurité - ce qui explique le message d'erreur que vous obtenez.


La page Politique de même origine sur wikipedia apporte des informations sur cette mesure de sécurité:

En résumé, la stratégie autorise les scripts s'exécutant sur des pages provenant du même site à accéder aux méthodes et aux propriétés des autres sans restrictions spécifiques - mais empêche l'accès à la plupart des méthodes et des propriétés sur les pages de différents sites.

Une séparation stricte entre le contenu fourni par des sites non liés doit être maintenue côté client pour éviter la perte de confidentialité ou d'intégrité des données.

14
Pascal MARTIN

Au lieu d'utiliser le référent, vous pouvez implémenter window.postMessage pour communiquer entre les iframes/fenêtres entre les domaines.
Vous publiez sur window.parent, puis le parent renvoie l'URL.
Cela fonctionne, mais cela nécessite une communication asynchrone.
Vous devrez écrire un wrapper synchrone autour des méthodes asynchrones, si vous en avez besoin de manière synchrone.

<!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>
6
Stefan Steiger

Vous avez plusieurs options:

  1. Étendez le domaine vers le bas (voir document.domain) dans la page contenant et le iframe à la même chose. Ils ne seront alors pas liés par des contraintes de "même origine".

  2. Utilisez postMessage qui est pris en charge par tous les navigateurs HTML5 pour cross-domain la communication.

1
SSS

Bon article ici: Communication inter-domaines avec iframes

Vous pouvez également définir directement document.domain de la même manière dans les deux cadres (même

document.domain = document.domain;

le code a du sens car réinitialise le port à null), mais cette astuce n'est pas générale.

0
Razoomnick