2011-12-14 23 views
2

これはWebKit固有のブラウザです(WebKit固有のもの、つまりiOS/Androidブラウザで動作させる必要がありますが、Chromeでテストしています)。JavaScriptでウィンドウとフレームの間でデータを共有する方法

私はページを持っています。ページには、別のドメインのコンテンツを含む1つ以上のiframeが読み込まれます。これらのiframeからメッセージ(postMessage()を使用して)を受け取る必要があり、特定のメッセージがどのiframeから来たのかを特定できる必要があります。

iframeのコンテンツが返されるようなiframe URLを投げることを含まない方法を見つけることができません。私はURLに憂慮する必要はありません。私は安全にそれを行うことができるという保証はありません(例えば、リダイレクトはパラメータを投げることができます)。

私は妥当だと思ったことを試しました。 iframe要素を作成すると(J/Sから実行されます)、要素にプロパティを関連付けました。「shared_secret」としましょう。フレームからメッセージイベントを取得したら、呼び出しフレームが作成された要素を探して、そのプロパティを読み取ろうとしました。

function onMessage(evt) { 
    var callerId = evt.source.frameElement.shared_secret; 
    // .... 
} 

window.addEventListener(message, onMessage); 

var frameEl = document.createElement('iframe'); 
frameEl.shared_secret = 'sommething blue'; 
frameEl.src = 'http://aliens.com/my.html'; 
somewhereInMyDoc.appendChild(frameEl); 

場合、フレームロード、それが実行される:

window.parent.postMessage('do you know who I am?', '*'); 

を但し、frameElement)が(上記のonMessageに未定義判明。セキュリティ上の理由から、親/子が同じドメインに属する場合は完全に機能します。

それは実際に皮肉です。 event.sourceはエイリアンウィンドウなので、親ウィンドウはevent.source.frameElementにアクセスできません。 frameElementはエイリアンウィンドウにあるため、iFrameウィンドウはwindow.frameElementを呼び出すことはできません。誰もそれにアクセスすることはできません。

それで、私は新たにロードされたフレームに設定できるトークンとして何かがありますが、何とか戻ってきますか?

ありがとうございます。

+0

あなたは子供のiframeから親ウィンドウにアクセスしようとしていますか? – Roman

+0

私はお互いからウィンドウにアクセスしようとしていません。私はメッセージAPIを使用していますが、私はどの子どもが電話しているのか知る必要があります。そして、事前に識別文字列に同意する方法はありません。 –

+0

event.originフィールドに必要な値はありませんか? http://dev.w3.org/html5/postmsg/#dom-messageevent-origin – Roman

答えて

6

は、ここで私はメッセージを送ったのiframeを見つけるために使用するものです!

1

これはhttps://stackoverflow.com/users/695461/dmosesと記されています。

実際には、frame要素のコンテンツウィンドウオブジェクトをmessageイベントのevent.sourceと比較することができます。実際には同じ場合はTRUEになります。

私の特別な問題を解決するために、私が作成したフレーム要素のリストを保持する必要があります(必要に応じて追加のプロパティを使用してそれらを振りかざします)。イベントが発生すると、すべて、contentWindowプロパティがevent.sourceプロパティと等しいものを探します。私たちがやった

UPDATE

は、いくつかの厄介なバグに遭遇しても、あなたは親ウィンドウから作成したのiframeの「ID」を置く必要があることが分かりました。特に、そのウィンドウ自体がiframe内にある場合。そうしないと、ブラウザが完全に異なる子フレームからメッセージを受信して​​いても、特定のブラウザ(Android 4.xは確かに知られています)では真の比較が行われます。パヴェルVeselovとDMosesへ

/** 
* Returns the iframe corresponding to a message event or null if not found. 
* 
* 'e' is the event object 
*/ 
function getFrameTarget (e) { 
    var frames = document.getElementsByTagName('iframe'), 
     frameId = 0, 
     framesLength = frames.length; 

    for (; frameId < framesLength; frameId++) { 
     if (frames[frameId].contentWindow === e.source) { 
      return frames[frameId]; 
     } 
    } 

    return null; 
} 

ありがとう:いくつかのコードを探している人のために

関連する問題