Flash Playerには、開発者の必要に応じて、SWFファイル間の通信を行うための方法がいくつか用意されています。それぞれの方法に、クロスドメイン通信の機能があります。どの方法が適しているかは、使用事例のシナリオと、2つのドメイン間にどの程度の信頼関係があるかによって異なります。
ソリューションは、直接通信と、共通のリソースを使用する通信に分けられます。直接通信を行う方法では、対象のSWFファイルが送信側によってロードされる必要があります。通信のための共通のリソースを作成した場合は、ロード操作は不要であり、複数のSWFファイル間で通信を行うことができます。
一般的な方法のリストと、その機能およびセキュリティに関して考慮する必要がある事項を以下に示します。
Loaderの使用による読み込みロード:
flash.system.Security.allowDomain()の使用によるクロススクリプトの許可:
Security.allowDomain()メソッドを含んでいるSWFだけに与えられます。Security.allowDomain()メソッドでは、複数のリモートドメインに対してアクセスを許可できます。LocalConnection:
LocalConnection.allowDomain()を使用すると、複数のドメインに接続を許可できます。ローカル共有オブジェクト:
localPathとsecureフラグの設定の影響を受けます。JavaScriptの中継:
allowScriptAccessの設定に依存します。Loaderクラスを使用する際のセキュリティ設定について詳しくは、Adobe LiveDocsのActionScript 3.0でのLoaderContextの使用に関する説明を参照してください。
LoaderContextパラメータの設定で指定されているドメインによっては、Loaderクラスを使用して読み込みロードまたはクロススクリプト通信を実行できます。コンテンツをロードする際は、2種類のドメインを指定できます。1つはセキュリティドメインで、これは通常、SWFがロードされた場所によって定義されます。セキュリティドメインは、SWFの読み込みロードを行うかどうかを判断するために使用されます。各セキュリティドメインには、コード内でのクラス間の継承とアクセス範囲を定義する「ApplicationDomain」を複数含めることができます。ApplicationDomainは、ActionScript 3.0で作成されたSWFファイルでのみサポートされます。アプリケーションドメインとセキュリティドメインはいずれも、LoaderのLoaderContextの設定で定義されます。
セキュリティドメインは、別のドメインからSWFファイルがロードされるときに割り当てられます。HTMLページのデフォルトでは、それぞれ異なるドメイン名から別々にロードされた2つのSWFファイルには、別々のセキュリティドメインが割り当てられます。ロードする側のSWFファイルが、コードにリモートSWFを組み込むことによってリモートSWFを明示的に信頼している場合は、それ自身のセキュリティドメインに直接リモートSWFを読み込むことができます。このプロセスを読み込みロードと呼びます。開発者は、読み込みロードを使用することにより、自分のドメインからロードするかのように別のドメインからリモートSWFファイルをロードできます。この方法は、リモートドメインからロードするコンテンツを完全に信頼できる場合にのみ検討するようにしてください。ActionScript 3.0での読み込みロードは、他人のコードのeval()を実行することと同じです。SWFファイルがそれ自体のセキュリティドメインに置かれたままである場合は、この節の後の方で説明するように、クロススクリプトの許可を使用して通信を許可する必要があります。
読み込みロードを実行して現在のセキュリティドメインにリモートSWFをロードするには、2つの方法があります。 Loader.loadBytes()を使用してSWFをロードする場合、LoaderContextがnullに設定されていれば、ロードする側のSWFのセキュリティドメインにそのSWFがデフォルトでロードされます。2番目の方法は、LoaderContextでSecurityDomainにcurrentDomainを指定する方法です。ロードされる側のSWFのセキュリティドメインは、ロードする側のSWFファイルのドメインにしか変更できません。また、リモートサーバ上に、現在のドメインによるSWFのロードを許可するcrossdomain.xmlファイルが存在する必要があります。
LoaderContextを使用するコード例を次に示します。
// This will result in import loading (the default for Flash Player) var ldr:Loader = new Loader(); var url:String = "http://www.unknown.example.com/content.swf"; var urlReq:URLRequest = new URLRequest(url); ldr.loadBytes(urlReq); // This will also result in import loading var ldr:Loader = new Loader(); var loader_context:LoaderContext = new LoaderContext() loader_context.securityDomain = SecurityDomain.currentDomain var url:String = "http://www.unknown.example.com/content.swf"; var urlReq:URLRequest = new URLRequest(url); ldr.load(urlReq,loader_context); // Load a SWF but leave it in its own security domain var ldr:Loader = new Loader(); var url:String = "http://www.unknown.example.com/content.swf"; var urlReq:URLRequest = new URLRequest(url); ldr.load(urlReq);
リモートSWFをロードするときは、アクセスによってそのSWFファイルが他のSWFコンポーネントに及ぼす影響と、ロード先のWebページへの影響の両方を考慮する必要があります。allowScriptAccessがAlwaysに設定されている場合、SWFファイルのロード方法に関わらず、ロードによってホストWebページのスクリプトへのアクセスが許可されます。allowScriptAccessがsameDomainに設定されている場合は、読み込みロードされたリモートSWFにホストWebページへのアクセスが許可されます。
アプリケーションドメインは、インタプリタがクラスを処理する方法と、ロードされる側のSWFに対してロードする側のSWFファイルのクラスに対するアクセスや継承を許可するかどうかを定義します。アプリケーションドメインはActionScriptコードの協調する単位の管理を目的としており、セキュリティ目的での使用を意図していません。これをActionScript 2.0またはActionScript 1.0で作成されたSWFファイルに適用することはできません。どのオプションが適切であるかは、個々のアプリケーションによって異なります。SWFをローダーのApplicationDomainの子としてロードする(デフォルトオプション)か、またはローダー自体のApplicationDomainにロードすると、ロードされた側のSWFが親SWFのクラスに対してアクセスや継承を実行できるようになります。 ロードする側のSWFに、ロードされる側のSWFにすぐに公開してはいけないクラスが含まれている場合、開発者はSWFをシステムのApplicationDomainの子としてロードして、ロードする側のファイルのクラスを継承しないようにする必要があります。しかし、この方法でも、子SWFファイルが他のApplicationDomainの場所を知っていれば、その定義を明示的に取得することができます。
これを行う方法のコード例を次に示します。
// Create the request and LoaderContext for the application domain request = new URLRequest(swfLib); var context:LoaderContext = new LoaderContext(); // Option 1: Loads the SWF as a child of the current domain context.applicationDomain = new ApplicationDomain(ApplicationDomain.currentDomain) // Option 2: Sets the application domain to the current domain context.applicationDomain = ApplicationDomain.currentDomain; // Option 3: This separates the loader and loadee entirely context.applicationDomain = new ApplicationDomain(null). // Option 4: A complex example demonstrating how to load a SWF // file into a new child of the current domain's parent's parent Content.applicationDomain = new ApplicationDomain(ApplicationDomain.currentDomain.parentDomain.parentDomain) // Load the request based on the context setting loader.load(request, context);
この節で説明している内容についてさらに詳しく知りたい場合は、Adobe LiveDocsの次のページを参照してください。
同じドメインから2つのSWFファイルをロードする場合、そのSWF間で通信を行ってデータと関数を共有できるようにするための方法はいくつかあります。 しかし、別々のドメインから2つのSWFファイルをロードする場合は、アクセス先のSWFファイル内でsystem.Security.allowDomain()を指定して特別にアクセスを許可しない限り、ファイル間でクロススクリプトによる通信を実行することはできません。allowDomainの設定では、一方向の通信だけを許可できます。2つのSWFファイルが双方向でデータを交換する必要がある場合は、両方のSWFファイルにallowDomainステートメントを含める必要があります(図1.を参照)。


図1.別のドメインにロードされたSWF間の通信を可能にするための、ActionScript 3.0でのsecurity.allowDomainの使用(上)またはActionScript 2.0でのallowDomainの使用(下)
HTTP経由でロードされるSWFファイルがHTTPS経由で提供されるSWFファイルのデータにアクセスするためには、特別なアクセス許可が必要です。その場合、security.allowInsecureDomain()の呼び出しを使用できます。このような種類のシナリオは、できる限り避けることを強くお勧めします。この種類の通信を使用すると、SSLによって保護されている重要なデータが、保護されていない環境に流出する恐れがあります。
Flash Playerのクロスドメインセキュリティ規則は、Flash Playerのセキュリティモデルと共に発展してきました。開発者は、SWFのコンパイル時に指定するPlayerのバージョンを決定する際に、その点を考慮に入れる必要があります。次の表に相違点を示します(表2.)。
表2.Flash Playerの各バージョンで実装されるクロスドメインセキュリティ規則
| クロススクリプトに関与するSWFの最新バージョン | 5 以前 |
6 | 7 | 8 以降 |
| allowDomain()の必要性 | いいえ | 必要(スーパードメインが一致しない場合) | 必要(ドメインが完全に一致しない場合) | 必要(ドメインが完全に一致しない場合) |
| allowInsecureDomain()の必要性 | - | - | 必要(HTTPからHTTPSへのアクセスを実行する場合。ドメインが完全に一致する場合もこれに含まれます) | 必要(HTTPからHTTPSへのアクセスを実行する場合。ドメインが完全に一致する場合もこれに含まれます) |
| allowDomain()またはallowInsecureDomain()を呼び出す必要があるSWF | 該当なし | アクセス先SWFファイル、またはアクセス先SWFファイルと同じスーパードメインにある任意のSWFファイル | アクセス先SWFファイル、またはアクセス先SWFファイルとまったく同じドメインにある任意のSWFファイル | アクセス先SWF |
| allowDomain()またはallowInsecureDomain()に指定できる項目 | 該当なし |
|
|
|
Flash Player 9では、このAPIの使用は呼び出し元のSWFファイルのみに適用され、同じドメインの他のSWFファイルには適用されません。
Flash Playerの動作が、Flash Player自体のバージョンではなく、FLAファイルからSWFファイルを作成するときにPublishの設定で選択したバージョンに基づいて定義される点に注意してください。 例えば、Flash Playerバージョン9でバージョン7用に公開されたSWFファイルを再生する場合は、バージョン7に沿った動作が適用されます。これによって、下位互換性が維持され、Flash Playerがアップグレードされてもデプロイ済みのSWFファイルの動作が変更されなくなります。
Security.allowDomain()メソッドは、クロススクリプトの実行、表示リストへのアクセス、Stageオブジェクトへのアクセスおよびイベントの検出のためのアクセス許可を付与します。これは、リモートドメインにHTMLからSWFへのスクリプトを許可するということも意味します。 HTMLからSWFへの通信については、「JavaScriptの中継」節で後ほど説明します。2つのドメイン間のクロススクリプトは、スクリプトを許可するアクセスで、アクセスを許可されるドメインを明示的に信頼できる場合にのみ許可するようにしてください。クロススクリプトでは、SWFのアクセス許可の付与に含まれるすべてのオブジェクトとメソッドへのアクセスが許可されます。
親が、ロードした直後のSWFとの間でクロススクリプトを実行できるかどうかを調べる必要がある場合は、ActionScript 3.0のLoaderInfoのchildAllowsParentプロパティを確認します。同様に、ロードされる側のSWFが、親と通信できるかどうかを調べるには、ActionScript 3.0のparentAllowsChildプロパティを確認します。