web-dev-qa-db-ja.com

<iframe> javascriptはドメイン間で親DOMにアクセスしますか?

別のドメインのページに埋め込まれたiframeのコンテンツを制御します。 iframe内のJavaScriptが親のDOMを変更する方法はありますか?

たとえば、iframedスクリプトで一連のhtml要素を親DOMに追加したいとします。これはかなり難しい注文のようです-考えですか?

編集:フラグメントIDメッセージング 」と呼ばれる手法が存在します。

編集:また、Firefox 3.5、Opera、Chrome(etc)はhtml5を採用しているようです "postMessage" api は、フレーム、iframe、ポップアップ間の安全なクロスドメインデータ転送を可能にします。これはイベントシステムのように機能します。IE8はこの機能をサポートしているようですが、これはおそらく少し意外です。

概要:いいえ、別のドメインからページのDOMに直接アクセス/編集することはできません。しかし、あなたはそれと通信することができ、それは協力してあなたが望む変更を加えることができます。

16
aaaidan

それを言うのは嫌いですが、セキュリティのために直接起こっていないことは99%確信しています。

ぜひお試しください こちら

うん

20
Andy Gaskell

可能です。

編集でpostMessageに言及するのは正しかった。見ている人のために、ドメイン間で通信するための優れた下位互換性のあるJavaScript専用の方法があります。短くて簡単なコードも。完璧なソリューション?親と子への変更を要求できる限り:

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

11
Kyle

はい、できます。
window.postMessageを実装して、ドメイン全体でiframeやウィンドウ間で通信できます。
しかし、非同期の方法でそれを行う必要があります。
同期で必要な場合は、非同期メソッドの周りにラッパーを実装する必要があります。

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

ここでは、子に変更を加え、postmessagesを親に送信します。例えばchild.htmでは、

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

親では、(receiveMessageで)eval(evt.data);を実行します。evalの使用は安全ではないため、代わりに列挙型を渡して、親ページに配置する必要がある対応する関数を呼び出します。

5
Stefan Steiger

AJAXの場合、サーバーはヘッダーAccess-Control-Allow-Origin: *を返し、クロスドメインアクセスを許可できます。多分それはIFRAMEのためにも働きます。

0
user836773

プロキシを使用せずにセキュリティの問題が発生すると思います。プロキシは非常に使用することができます。あなたはそれらの1つを試すことができます:

(1)a PHPベースのプロキシ (便利なリンクの間に多くの広告があるので注意してください)

(2)Apache .htaccessプロキシ-ドメインにサブディレクトリproxyを作成し、そこに.htaccess以下を含むファイル:

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

Picasaweb.google.comの代わりに他のドメイン名を入力します

個人的には、Apacheプロキシの使用を好みます

0
warpech