LoaderやURLLoaderのcrossdomainの扱いについてちょっとハマったのでエントリにしてみます。

別ドメインデータロードのセキュリティとcrossdomain.xml

まずクロスドメインポリシーの簡単なおさらいです。Flashが別ドメインのデータをロードする際、クロスドメインポリシーファイルを参照することでセキュリティチェックがなされます。crossdomain.xmlにて許可が出ていない場合、データに対するバイナリでのロード、参照などが不可能になってしまいます。

例えばこんなコード。

// http://site.kayac.com/flash.swf のソースコード
var loader:Loader = new Loader();
var req:URLRequest = new URLRequest('http://data.kayac.com/img.png');
var context:LoaderContext = new LoaderContext(true);
loader.load(req, context);
addChild(loader);

//ロード完了後・・
var bmd:BitmapData = new BitmapData(loader.width, loader.height);
bmd.draw(loader);
//↑crossdomain.xmlで許可されていない場合、ここでエラーになる

画像をLoaderで読み込んで表示するだけなら大丈夫だけど、BitmapData.drawしようとしたらエラーが出ちゃった!→crossdomain.xmlが置いてなかった(´・ω・`)っていうパターンのやつです。

crossdomainが置いてあるのに、まだエラーが出る!?理由はリダイレクト

さてここからが本題なのですが、例としてFacebookユーザのアイコン画像をロードして表示してみましょう。アイコンを取得するには、
http://graph.facebook.com/ユーザid/picture
をリクエストすればそのまま画像が帰ってきます。例えば私はundo0530っていうアカウントなのでhttp://graph.facebook.com/undo0530/pictureとなります。graph.facebook.com上のクロスドメインポリシーファイルも許可を出しているので、Flashからロードしても大丈夫なはずです。
さぁ、この画像をロードして、とりあえずBitmapData.drawしてみましょう。

facebookのアイコン画像ロード→BitmapData.draw - wonderfl build flash online

はい、エラーです。確認してみると、

SecurityError: Error #2122: セキュリティサンドボックス侵害 : BitmapData.draw:
http://swf.wonderfl.net/....swf

http://profile.ak.fbcdn.net/....jpg
にアクセスできません。
ポリシーファイルが必要ですが、このメディアがロードされたとき、checkPolicyFile フラグが設定されませんでした。

とのことです。実はgraph.facebook.comのAPIを使ってアイコン画像を取得すると、リダイレクトされたprofile.ak.fbcdn.netに置かれているアイコン画像が返ってくるため、Loder.loadの前にチェックしたポリシーファイルが無駄になってしまうわけです。
これは困った・・・

(ちなみに、profile.ak.fbcdn.net/crossdomain.xmlはちゃんと許可出ています。)

リダイレクトするAPIでもチェックを有効にするには?

要は「リダイレクトなAPIの場合でも、リダイレクト先のポリシーファイルをチェックできればいい」わけですが、実はコレ、URLLoaderが可能にしてくれます。

URLLoader.dataFormatをBINARYに設定すると、URLLoader.loadの前に自動的にポリシーファイルをチェックしてくれます。そしてこのチェック機能が、リダイレクトしちゃうAPIでも有効なんです。

var urlLoader:URLLoader = new URLLoader();
urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
var req:URLRequest = new URLRequest('http://graph.facebook.com/undo0530/picture');
urlLoader.load(req);

このコードを実行しつつネットワークを監視してみると、graph.facebook.com/crossdomain.xmlをチェックしてからAPIを叩き、次にリダイレクト先のprofile.ak.fbcdn.net/crossdomain.xmlをチェックして、そして最終的に画像のバイナリデータを取得することができたようです。

URLLoaderで解決 forked from: facebookのアイコン画像ロード→BitmapData.draw - wonderfl build flash online

サウンドデータをストリーミングするならこんな感じ・・・(これはもっとスマートな方法があるのでは)

イシカワタケループ -soundSpectrumCity- - wonderfl build flash online

すごいぞ、URLLoader!というお話でした。

HTML5飯