rascut で外部ファイル(img, xml) を読み込む時は要注意
階層
. |-- 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