HTML5 のクロスドキュメント メッセージングを詳しく見る

黄舟
リリース: 2017-03-25 16:13:07
オリジナル
1522 人が閲覧しました

クロスドキュメント メッセージング (XDM とも呼ばれます) は、異なるドメインのページ間でのメッセージの送信を指します。たとえば、www.w3cmm.com ドメインのページは、埋め込み frame にある p2p.w3cmm.com ドメインのページと通信します。 XDM メカニズムが登場する前は、この種の通信をより確実に実装するには多大な努力が必要でした。 XDM はこのメカニズムを標準化し、ドキュメント間の通信を安全かつ簡単に実装できるようにします。

XDM の中核は postMessage() メソッドです。 HTML5 仕様では、XDM 部分以外の他の部分でもこのメソッド名が言及されますが、それらはすべて同じ目的、つまりデータを別の場所に渡すためのものです。 XDM の場合、「別の場所」とは、現在のページに含まれる

postMessage() メソッドは、メッセージとメッセージ受信者の送信元ドメインを示す文字列という 2 つのパラメーターを受け取ります。 2 番目のパラメータは、安全な通信を確保し、ブラウザが安全でない場所にメッセージを送信するのを防ぐために非常に重要です。次の例を考えてみましょう。

var iframWindow = document.getElementById("myframe").contentWindow;
iframWindow.postMessage("A secret", "http://www.w3cmm.com");
ログイン後にコピー

コードの最後の行は、インライン フレームにメッセージを送信しようとし、フレーム内のドキュメントが「http://www.w3cmm.com」ドメインから送信される必要があることを指定します。ソースが一致する場合、メッセージは iframe に配信され、そうでない場合、postMessage() は何も行いません。この制限により、ウィンドウ内の位置が知らないうちに変更されることが防止されます。 postMessage() に渡される 2 番目のパラメータが「*」の場合、メッセージを任意のドメインからドキュメントに送信できることを意味しますが、これはお勧めしません。

が XDM メッセージを受信すると、window オブジェクト のメッセージ イベントがトリガーされます。このイベントは非同期でトリガーされるため、メッセージの送信からメッセージの受信 (受信ウィンドウのメッセージ イベントのトリガー) までに遅延が発生する可能性があります。 message イベントがトリガーされた後、onmessage ハンドラーに渡されるイベント オブジェクトには、次の 3 つの重要な情報が含まれます。

data: postMessage() の最初のパラメーターとして渡される文字列データ。
origin: メッセージを送信するドキュメントが存在するドメイン (「http://www.w3cmm.com」など)。
source: メッセージを送信するドキュメントのウィンドウ オブジェクトのプロキシ。このプロキシ オブジェクトは主に、前のメッセージを送信したウィンドウで postMessage() メソッドを呼び出すために使用されます。メッセージを送信しているウィンドウが同じドメインからのものである場合、このオブジェクトは window です。

メッセージを受信した後、送信ウィンドウのソースを確認することが重要です。 postMessage() メソッドに 2 番目のパラメーターを指定して、ブラウザーが不明なページにメッセージを送信しないようにするのと同じように、onmessage ハンドラーでメッセージのソースを検出すると、受信メッセージが既知のページからのものであることを確認できます。基本的な検出モードは以下のとおりです。

var EventUtil = {
    addHandler: function (element, type, handler) {
        if (element.addEventListener) {
            element.addEventListener(type, handler, false);
        } else if (element.attachEvent) {
            element.attachEvent("on" + type, handler);
        } else {
            element["on" + type] = handler;
        }
    }
};

EventUtil.addHandler(window, "message", function (event) {
    //确保发送消息的域是已知的域
    if (event.origin == "http://www.w3cmm.com") {
        //处理接收到的数据
        processMessage(event.data);
        //可选:向来源窗口发送回执
        event.source.postMessage("Received!", "http://p2p.w3cmm.com");
    }
});
ログイン後にコピー

それでも皆さんに思い出していただきたいのは、event.source はほとんどの場合、ウィンドウ オブジェクトの単なるプロキシであり、実際のウィンドウ オブジェクトではないということです。言い換えれば、このプロキシ オブジェクトを通じてウィンドウ オブジェクトに関する他の情報にアクセスすることはできません。このプロキシを通じて postMessage() を呼び出すだけであることに注意してください。このメソッドは存在せず、いつでも呼び出すことができます。

XDM にもいくつかの癖があります。まず、postMessage() の最初のパラメータは最初は「常に文字列」として実装されました。ただし、後にこのパラメータの定義が変更され、任意のデータ構造を渡せるようになりました。ただし、すべてのブラウザーがこの変更を実装しているわけではありません。安全を期すために、postMessage() を使用する場合は、文字列のみを渡すことをお勧めします。構造化データを渡したい場合、最良のオプションは、最初に渡されるデータに対して JSON.stringify() を呼び出し、結果の文字列を postMessage() を通じて渡し、次に onmessage イベント処理を行うことです。 プログラム内で JSON.parse() を呼び出します。

インライン フレームを介して他のドメインからコンテンツを読み込む場合、XDM を使用すると非常に便利です。したがって、このメッセージ配信方法は、マッシュアップやソーシャル ネットワーキング アプリケーションで非常に一般的です。 XDM を使用すると、埋め込みフレームに対してのみ XDM 経由で通信するため、