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

By | 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

trace をファイル出力するための mm.cfg 設定の注意点(mac)

HDD 入れ替えで /Library とかをいれなおしたために trace 出力や flashswitcher が
動かなくなってることに気づいた。
このくそ忙しい中に環境作りなおすはめに。
覚えてないんで無駄にハマった。。。orz
もぉはまりたくないので memo を残しとくことに。

ちなみに環境は Mac OS 10.5 です。
mm.cfg に設定を書いて trace がファイル出力されるようになる。
設置場所は /Library/Application\ Support/Macromedia/,
/Users/[username]/ のどちらでも確認はとれた。

mm.cfg の内容

1
2
ErrorReportingEnable=1
TraceOutputFileEnable=1
1
2
PolicyFileLog=1
PolicyFileLogAppend=1

これをいれてしまうと動かない。
それでダダはまり。

flashswitcher は前記事を参照<mac で flashswitcher を使う時の注意点>

HDD いれかえた後にシステムいれなおしたのがあだとなった。
あと mac だと Flex Builder のプロファイラが動かないっぽい。
プロファイラがないとパフォチュで凄い不便すぎる。
何か良いのないかなぁ〜

参考資料

MacでFlashPlayer9のTraceが出力されない問題解決 その2
Flash Player 9,0,115,0 で mm.cfg の位置が変わってますよー (Mac)
デバッガ版の Flash Player の構成

ASDebugger リリースしました

By | 2008年12月18日

ASDebugger という debug ツールを作ってます。
で、ある程度まとまった (正確には機能を削ったw) ので spark にあげました。
ほんとならあーしたかったとかあるけど、そのうち反映させます。
以前作った Dumper を組み込んだデバッグするためのライブラリって感じです。

簡単にいうと plugin 形式でバシバシ機能拡張でき、出力先をオレ様ロガーをならってプラガブルに設定できるといったものです。
そして誰でも簡単に Debugger(出力先) や Plugin を追加することができます。
今のところ Debugger は SimpleLogger(予定), Trace, Firebug, Thunderbolt には対応しています。
(※id:borealkissさんには確認してもらってるとこです。)
これって何がいいかって言うと何も考えずに plugin 書くだけで
出力先のことは気にせずに 作れば作るほど便利になっていきます。
Dumper はすでに書き直して組み込んでます。
後は忘れがちな FlashPlayer のバージョンや使用メモリやら security やらのメソッドもはやしてます。

これだけだとわかりにくいんで サンプルは spark の方にあるんでそっちを見てください。
なんだかんだで、ある程度は形になったってレベルなんで、もっと使いやすいようにせねば。そのうちよします。
特に nobu さんや yossy さんとかとか。つっこみ歓迎です。
むしろ勝手になおしちゃってもいいんでw
あと ASReflect に依存しているので 使用の際は気をつけてください。

追記 2008/12/28 11:17:20
ASDebuger は間違いで ASDebugger でしたw
すでに修正したのをコミットしてます。
随時ドキュメントに関しては変更していきます。

actionscirptで変数のブロックスコープを実現する

By | 2008年9月17日

昔にactionscriptの変数のスコープがfunctionスコープということを知らずに凄いハマったことがあって
それ以来は気をつけてはいたんですが、どうやらブロックスコープを実現できるみたいなので試してみた。

結論から言うと、withを使う。
actionscirpt1のころからwithの存在を知ってはいたけどコード量を短くする以外に使い道もわからなく
そんなに困ることもなく存在すら忘れ去れそうになっていましたw

でも、この子は非常に優秀です。できる子でした。
perlでいうlocalみたいなことができるんです。
素晴らしすぎます。今まで知らなかったことが残念で仕方ありません。

actionscript、javascript共に試したコードをつるしときます。

ver FlashIDE

1
2
3
4
5
6
7
8
9
10
11
var hoge:Number = 8;
 
trace("default:" + hoge);               // 8
(function():void {
    var hoge:Number = 10;
    trace("function:" + hoge);               // 10
})();
 
with( {hoge:1} ) {
    trace("with:" + hoge);               // 1
}

ver flex SDK(上のFlashIDEと対してかわりはありません。)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package {
    import flash.display.Sprite;
 
    public class Hoge extends Sprite{
        public function Hoge() {
            var hoge:Number = 8;
            trace("default:" + hoge);               // 8
 
            (function():void {
                var hoge:Number = 10;
                trace("function:" + hoge);               // 10
            })();
 
            with( {hoge:1} ) {
                trace("with:" + hoge);                // 8 <- これがおかしい
            }
        }
    }
}

ver javascript

1
(function(){var hoge=10;with({hoge:4}){alert(hoge);}alert(hoge);})();   // 4が表示され、次に10が表示される

Flash IDEから使用した場合は問題なくブロックスコープが実現されています。

ただ、、、、
Flex SDKを使ってコンパイルする際には、withを使ってのブロックスコープが実現されません。
FlashPlayerのせいでもなさそうですし、おそらくはコンパイル時のSDKの実装によるものだと思います。

ちなみにSDKのバージョンはVersion 3.1.0 build 2710です。
普段はSDKをメインに開発してるので結局はfuncionを使っての方法でやるしかなさそう。。。

FlashDevelopも確かSDKのはずだからできないのかな??
windowsないんで試せる人いたら教えてほしーっす。
テンションあがったのになぁー

StreetView使ってみた

By | 2008年9月7日

uranodaiさんがsparkにコミットしたStreetviewを使って試してみた。

雑感だけど凄い便利にさわれた。
簡単にstreetviewをいじって遊べた。
んでwiiハンドルで操作するのは気になるのは何点かあるけど、
とりあえず形にはなった感じ。

あとは修正して問題なければ公開する予定。

ちなみに今回使用したconfigファイル。
(※)ソースは汚いのでおいおい公開します。

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://ns.adobe.com/air/application/1.0">
    <id>StreetViewWii</id>
    <filename>StreetViewWii</filename>
    <name>StreetViewWii</name>
    <initialWindow>
        <content>StreetViewWii.swf</content>
    </initialWindow>
</application>

公開証の作り方

1
adt -certificate -cn SelfSigned 1024-RSA [証明書名] [パスワード]

テスト

1
adl [大元のソースコード]

air用swf作成

1
amxmlc [大元のソースコード]

airファイル作成

1
adt -package -storetype pkcs12 -keystore [証明書名] [作成するairファイル名] [configファイル] [air化したいswfファイル]

これでおk。
ちなみに全てFlex SDKでターミナルから叩いてやりました。
uranodaiさんどもっす!!