Loader系のcrossdomainと、HTTPリダイレクトしちゃうAPIのお話
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!というお話でした。