2012年1月24日火曜日

XDMの基礎知識

XDM - Cross Document Messaging -

AJAXでは,セキュリティの都合により,そのWebページが格納されているサーバとしか通信を行えませんでした.これに対してJSONPを使って回避することも可能ですが,JSONPはscriptタグによるJavaScriptのロードそのものであり,トリッキーなコードになることは否定できません(jQueryを使うことで回避できますが,ここでは置いておきます).そんな時に使われるのが,XDMです.

XDMとは,大雑把にいってしまうと,iframeを作う技術です.そうです.frameは抹殺されたのですが,iframeは残っています.それで,iframeの特性として「表示上は同一ページだが,セキュリティ上の扱いは親フレームとは別に扱う」ことになっています.すなわち,親フレームとは異なるサーバに置いてあったとしても,子フレームは自身が格納されているサーバとは通信を行えることになります.偉そうに言ってますが,ここまでは昔から可能でした.

昔と違うのは,親フレームと子フレームの間の通信が(別サーバであっても)可能になったことです.ただし,悪意のあるページからiframeで呼び出されて好き勝手されては困るので,通信相手のサーバ情報を取得して,正規の通信であることを確認可能となっています.

XDMによる送信(親フレーム側)

フレーム間の通信には前回WebWorkersでも使用した「postMessage」と「addEventListener」を使います.レシーバの指定が少々異なるので,例を使って説明します.まずは,localhostにWebサーバがあり,以下のように,送信ボタン,iframe,受信データの表示領域が定義されているとします.

このとき,親フレームから子フレームへの送信は以下のように行います.

順に説明すると,1行目はボタン要素の取得,2行目はiframe要素.contentWindowによって,通常のページで言うwindowに相当するオブジェクトを取得しています.

3行目からは,ボタンクリックのイベント定義です.4行目でdataという名前のハッシュを作り,helloという文字列と現在時刻を収めます.

5行目が子フレームへの送信です.第1パラメータが送信内容で,先ほど作成したdataをJSON化したものです.今のところ,文字列でないと送信できないので,その対策です.そして,第2パラメータが子フレームが格納されているサーバを表します.つまり,プログラム作成者が子フレームのサーバをしっかりと把握している必要があります(プログラムで動的にサーバを取得する場合はこの限りではありませんが,どのような状況で動的に取得するのかは不明です).もし子フレームのサーバ指定を間違えると,例えば間違えて「http://hoge.com」と指定すると「Unable to post message to http://hoge.com. Recipient has origin http://hoge.com.」というエラーがコンソールに表示されます(Google Chromeの場合).

子フレーム側の記述

一方,子フレーム側でデータを受け取るには,addEventListenerを使います.ここでは,親フレームから送信された内容を,そのまま返信する例を使って説明します.

1行目はXDMにより,メッセージを受け取った際のイベント定義です.2行目は,通信相手のサーバ情報の確認です.この例で分かるように,event.originで通信相手のサーバ情報を確認できるので,セキュリティ面からきちんと確認しましょう.

3行目はデータの返信です.親フレームの要素を取得する方法が分からなかったため,event.source(送信してきた要素)に対してpostMessageしています.パラメータは先程と一緒です.あ,event.dataで送られてきた内容を取得できるので,取り出して加工したい場合はJSON.parse( event.data )などとして使ってください.

親フレーム側の受信方法

最後に,親フレーム側での受信方法です.やり方は子フレームの場合と全く一緒です.ここでは,送られてきた内容をパースして,表示領域に貼り付ける所まで一緒に書いておきます.

1, 2行目は子フレームと全く一緒の記述方法ですが,メッセージを受け取った際のイベント定義と,送信元のサーバ情報のチェックです.3行目は送られてきたデータをパースして変数dataに格納します.4行目,5行目は送信元サーバ情報と送信内容を変数outに収めます.そして,6行目で表示エリアにoutの内容を貼り付けます.

ソースコード

今回のサンプルコードを示します.まずは親フレームです.好きな名前で保存してください.localhost以外のサーバに置く場合は17行目と21行目を変更してください.

続いて子フレームです.ファイル名はframe.htmlで保存してください.ファイル名を変えたい場合は,親フレーム側の9行目を変更してください.localhost以外のサーバに置く場合は11行目を変更してください.

XDMにより,親フレームと子フレームの間の通信が(それなりに)簡単に記述できるようになりました.実際に使用する際には子フレーム側を別サーバに置くことがあると思います.その場合はpostMessageや送信元サーバのチェック部分を書き換えてください.いずれも,そのファイルが格納されているサーバではなく,通信相手のサーバを記述します.

このエントリーをはてなブックマークに追加

0 件のコメント:

コメントを投稿