rascut で外部ファイル(img, xml) を読み込む時は要注意

By admin | 2009年1月18日

階層

.
|-- data.xml
|-- Test.as

Test.as

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package {
    import flash.net.URLLoader;
    import flash.net.URLRequest;
    import flash.display.Sprite;
    import flash.events.Event;
 
    public class Test extends Sprite {
        private var XML_URL:String = "http://example.com/data.xml";
        public var loader:URLLoader = null;
 
        public function Test() {
            loader = new URLLoader();
            loader.addEventListener(Event.COMPLETE, onXMLLoaded);
            loader.load(new URLRequest(XML_URL));
        }
 
        private function onXMLLoaded(e:Event):void {
            trace(loader.data);
        }
    }
}

実行コマンド

rascut -s Test.as

これで http://localhost:3001/ にアクセスすると XML を読み込む swf が表示される。
で、ここからが問題。
URLLoader を使って外部リソースの読み込みを行う際に XML_URL を相対パスで指定すると
loader.data の中身が SWF を埋めこんでる HTML になります。

<html>
    <head>
      <title>Rascut</title>
      <style>
      * {
          margin:0;
          padding:0;
      }
      #content {
          text-align:center;
      }
      </style>
      <script type="text/javascript" src="/js/swfobject.js"></script>
          <script type="text/javascript">
    var Rascut = new Object;
 
    Rascut.xhr = (function() {
      if (typeof XMLHttpRequest != 'undefined') {
        return new XMLHttpRequest();
      } else {
        try {
          return new ActiveXObject("Msxml2.XMLHTTP");
        } catch(e) {
          return new ActiveXObject("Microsoft.XMLHTTP");
        }
      }
    })();
 
    Rascut.reloadObserver = function() {
        var x = Rascut.xhr;
        x.open('GET', '/reload?' + (new Date()).getTime(), true);
        x.onreadystatechange = function() {
          try {
            if (x.readyState == 4) {
              if (x.status == 200 && Number(x.responseText) == 1) {
                // thanks os0x!
                so.attributes.swf = so.attributes.swf + '+';
                so.write('content');
                Rascut.reloadObserver();
              } else {
                setTimeout(Rascut.reloadObserver, 5000);
              }
            }
          } catch(e) {
            setTimeout(Rascut.reloadObserver, 5000);
          }
        }
        x.send(null);
    }
 
    Rascut.swf = function() {
       return document.getElementById('idswf');
    }
 
    Rascut.reloadObserver();
    </script>
 
    </head>
    <body>
      <div id="content"></div>
 
      <script type="text/javascript">
       var so = new SWFObject("/swf/Test.swf?" + (new Date()).getTime(), "idswf", "100%", "100%", '9', '');;
       window.onload = function() {
 
         so.addVariable('rascut', 'true');
         so.write("content");
       }
      </script>
    </body>
</html>

原因は簡単で、相対パスで指定すると HTTP ベースなので
http://localhost:3001/data.xml を取得しにいきます。
直接アドレスバーで叩くとわかりますけど http://localhost:3001 に
アクセスした時の HTML が返ってきます。

で、考えた対策
(1). XML_URL を file://〜 で指定
(2). localhost に apache(web server) をたててそこにアクセス(レンタルサーバとかでもおk)
(3). グローバルセキュリティの設定を許可(*)して data.xml にアクセスできるようにし flash player で起動
の3通り。

それぞれ試した結果
(1) はセキュリティサンドボックスのエラーが出て厳しそう。
  (追うのがめんどくさくなったw おそらく securityLevel 周りをいじればいけそう)
(2) これはすぐにできた。一番、無難そう。
  ただ別ドメインに置く場合は crossdomain.xml をドキュメントルートに
  置いておかないとロードすることができないので注意。
  (ちなみに flash player 10 で 9 の時と変わってたので、
  少し結構はまりました。crossdomain については後々まとめるつもり。)
(3) てっとり早いけど、rascut の恩恵が少なくなる。
  確認のために毎回起動するってめんどくさい。

というわけで、(2) と (3) を満たすように変更してみた。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package {
    import flash.net.URLLoader;
    import flash.net.URLRequest;
    import flash.display.Sprite;
    import flash.events.Event;
    import org.libspark.utils.Dumper;
 
    public class Test extends Sprite {
+        private var XML_URL:String = "data.xml";
        public var loader:URLLoader = null;
 
        public function Test() {
            loader = new URLLoader();
+            var host:String = '';
+            if (this.root.loaderInfo.parameters.rascut)
+                host = 'http://example.com/';
 
            loader.addEventListener(Event.COMPLETE, onXMLLoaded);
+            loader.load(new URLRequest(host + XML_URL));
        }
 
        private function onXMLLoaded(e:Event):void {
            trace(loader.data);
        }
    }
}

変更した場所は + をつけてます。
これで少しは快適に読み込みできるようになったかな。
3001 ポートでそのままリソースにアクセスできればベストなんだけどな〜
そのうちコード見てみることにする。

ちなみに設置した crossdomain.xml はこんな感じ。

<?xml version="1.0"?>
<cross-domain-policy>
  <site-control permitted-cross-domain-policies="all"/>
  <allow-access-from domain="*"/>
</cross-domain-policy>

site-control を追加しないと flash player 10 だと下記のようなエラーがでて読み込めないので注意

警告 : ドメイン cdn.slideshare.net にはメタポリシーが指定されていません。デフォルトのメタポリシー 'master-only' を適用しますが、この設定は推奨されていません。こ
の問題の解決方法については、http://www.adobe.com/go/strict_policy_files_jp を参照してください。

(*)グローバルセキュリティの設定でセキュリティを緩和したいファイル or ディレクトリを追加すれば OK

コメントはまだありません

コメントはまだありません。

このコメント欄の RSS フィード TrackBack URI

コメントをどうぞ

WordPress Themes