- 2009-10-06 (火) 14:14
- ActionScript | サーバ管理
かなり前に予告したゲームアップローダの制作を少しずつ進めています。
これまでのブログのプラグインを使用したものに比べて、ファイルをアップロードや設定がかなり楽になるはずです。また、アップロードしたゲームは自習室のトップで公開されるだけでなく、iframeタグを使って他のサイトやブログに貼れるようにする(Google MapやYotubeのようにする)予定です。
さてこのアップローダは、フロントエンドをAdobe Flex 3で、バックエンドをPHPで作っている――たとえば「アップロード」ボタンを押すと、ActionScirptでuploadfile.phpを呼び出して処理させる仕組み――のですが、ファイルのダウンロードの部分だけがなぜかAdobeのドキュメント通りに動かなかったため、ここにメモしておきます。
Flexでファイルをアップロード・ダウンロードするには、FileReferenceというクラスを使います。これはファイルや保存先を選ぶダイアログボックスを出した後、Webサーバにファイルを要求するリクエストを送る働きをします。
Adobeのサンプルによると、アップロード時にはサーバ側のアップロード用スクリプトを指定する必要があるのですが、ダウンロード時は特にそういうものは不要でdownloadメソッドを呼び出すだけでいいと書いてあるのですが、これがなぜかうまくいかない。
downloadメソッドの制限として、
1)ボタンなどのクリックイベントハンドラから呼び出さなければいけない
ユーザーが知らないうちにローカルへのダウンロードをさせないため。
2)FileRefenceクラスのインスタンスはクラスの変数に代入する
ローカル変数に入れておくとダウンロードしなくなる。バグらしい。
というものがあるのですが、どちらを満たしていても上手く行かない。
結局、サーバサイドにもダウンロード用のスクリプトを書いて解決しました。これはバグとかではなく、おそらくサーバ側(テスト環境のXAMPP)が、downloadメソッドが送るリクエストに応答する設定になってないんだと思います。
結局、こんな感じにしました。ファイル名はGETメソッドで渡してます。
Flex側
//ダウンロード(PHPスクリプトが必要)
private var downref:FileReference = new FileReference();
private function clickDownload(e:Event):void{
if(this.dg_files.selectedItems.length<1) return;
this.filetoolbar.enabled = false;
var item:Object = this.dg_files.selectedItem;
var request:URLRequest = new URLRequest("downloadfile.php?basdir=" + this.basedir
+"&downfname=" + item.fname);
this.downref.addEventListener(Event.COMPLETE, this.downloadComplete);
try{
this.downref.download(request,item.fname);
}catch(error:Error){
Alert.show("dwn er"+item.fname);
}
}
private function downloadComplete(e:Event):void{
this.filetoolbar.enabled = true;
Alert.show("ダウンロード完了","ゲームアップローダ");
}
PHP側
<?php
//ログインチェック
/* ダウンロード用のHTTPヘッダ送信 */
$dirpath = "files/".$_REQUEST["basdir"];
$fname = $_REQUEST["downfname"];
$path_file = $dirpath."/".$fname;
if (($content_length = filesize($path_file)) == 0) {
die("***..***".$path_file);
}
//テキストファイルのときはヘッダーを変える
if(preg_match("/\.(txt)$/",$path_file)>0){
header("Content-Type: text/plain");
} else {
header("Content-Type: application/octet-stream");
header("Content-Transfer-Encoding: binary");
}
header("Content-Disposition: attachment; filename=\"".$fname."\"");
header("Content-Length: ".$content_length);
$handle = fopen($path_file, 'rb');
while (!feof($handle))
{
echo fread($handle, 4096);
ob_flush();
flush();
}
fclose($handle);
?>
フロントエンドをFlexにすると細かい部分が作り込みやすくて楽なのですが(いちいちページロードもないし)、見た目はWebページの一部なのに実際は別空間になっている、つまりそれ自体が独立した1つのブラウザになっていることを意識しないといけないあたりがちょっと戸惑いますね。PHPのセッションも切れてしまうので色々小細工が必要なんだとか。
- Newer: 【告知】ゲームアップローダーをテスト公開!
- Older: [雑記]Google App Engine
Comments:0
Trackbacks:0
- Trackback URL for this entry
- http://i-libro.net/wpmu/blog/archives/368/trackback
- Listed below are links to weblogs that reference
- 【ActionScript】ゲームアップローダとFileReferenceクラス from わくわくプログラミング自習室 Blogs
