2011-07-19 160 views
1

クロスドメイン通信の問題を回避するために、HTML5の新しいpostMessage機能を使用しているコードがあります。私はコンテンツを正しく読み込んだiFrameにメッセージを投稿しているかどうかを検出する方法を見つけようとしています。フレームが正しく読み込まれなかった場合、postMessageはこれを知らず、無意味なフレームにメッセージを投稿します(コンテンツが読み込まれているかどうかにかかわらず、メッセージがフレームに配信されていると仮定します)。HTML 5 PostMessage/iFrameの読み込みに失敗しました

これが私たちのワークフローです:

  1. それは別のドメインからのプロキシページに設定したソースだと順番にユーザー負荷http://www.a.com/specialpage.aspx
  2. a.com/specialpage.aspxが子供iFrameをロードし、としてhttp://www.b.com/lookatmyproxy.htmを言います例。
  3. ユーザーは何らかの操作を行い、ボタンをクリックします。
  4. window.postMessageは、フレームが読み込まれたプロキシによってピックアップされる子フレームにメッセージを投稿するために使用されます(b.com/lookatmyproxy。 htm)。受信後、メッセージは検証され、処理され、返信は親フレーム(a.com/specialpage.aspx)にポストバックされます。
  5. ユーザーはその行動の結果を表示し、誰もが満足しています。

問題が発生するシナリオは、b.comがダウンしていて、プロキシがiFrame内で読み込まれなかった場合、postMessageが起動して忘れてしまい、親フレームが何らかのエラーや応答を受け取ることがないということです。セキュリティ上の懸念やiframeの性質によって、プロキシが正しくロードされたかどうかを調べるために、フレームの内容やステータスを確認できないようです。 a.comとb.com(a.com.comはa.com/relayへの投稿、b.com/proxyへの投稿など)の間で、私たちが制御しているいくつかのタイムアウトロジックを持つリレーを置くことができました。しかし、それは複雑すぎるようです。

iFrameをチェックして内容が正しく読み込まれているか、postMessageが読み込みに失敗したフレームに配信していることを検出する方法はありますか?

答えて

2

これは最もクリーンな回答ではありませんが、問題を解決できました。私が見つけたのは、セキュリティによって他のフレームから情報を読み取らせることはできませんが、いくつかの関数を呼び出すことができる古い文書でした。古いブラウザでは、これはフレームをトリックしてフラグメントを互いに設定し、アクションを起こさせるために使用されました。良いリファレンスはここにある:

http://softwareas.com/cross-domain-communication-with-iframes

のpostMessageが許可されているので、私のプロキシが最初に行うことは、それが存在する場合、その親フレームに「ロードされた」のメッセージを投稿しています。私のページは、そのメッセージを聞いて、彼らはそれがプロキシが正しくロードされていることを示すために受信したときに変数を設定し、物事の反対側に

//tell the parent that we're functional 
var data = '{ "action" : "Loaded" }'; 
if (parent && parent.frames && parent.frames[0] && parent.frames[0].content) { 
    parent.frames[0].content.postMessage(data, '*'); 
} 

window.addEventListener("message", function (e) { 
    if (e.domain == undefined) { 
     //do something 
    } 
}, false); 

:プロキシは、次のようになります。メッセージを受け取らない場合、すべてのアクションはプロキシが利用できないと想定し、UIはそれに応じて反応してユーザーの操作をブロックします。これは次のようになります。

$(document).ready(function() { 
    window.addEventListener("message", function (e) { 
     var args = (e.data && (e.data.length > 0)) ? JSON.parse(e.data) : {}; 
     if (args.action) { 
      if (args.action == 'Loaded') { 
       if (typeof ProxyLoaded_success == 'function') { 
        ProxyLoaded_success(args); 
       } 
      } 
     } 
    }, false); 
}); 

var proxyLoaded = false; 
function ProxyLoaded_success(args) { 
    proxyLoaded = true; 
} 

function abc() { 
    if(proxyLoaded == true) { 
     //do something here 
    } else { 
     alert("proxy didn't load. call support"); 
    } 
} 
関連する問題