flashでJSONを使う
普通にJSON.as(ActionScript3じゃないほう)使うだけでJSONが使えます。mtascの場合だと、JSON.asをJSON利用コードと同じディレクトリに配置して、
var json_str:String = JSON.parse( '{"foo":"foo_text"}' ); var o:Object = JSON.parse( json_str ); log( o.foo );
というように使う。
(個人的に)問題はサーバー間通信時で、割と複雑なデータをflashでサーバー間通信する場合、普通はXMLなんですかね?よくわからないけどぱっと見た感じそんな感じを受け、JSON使うのにXMLで包むのもどうかと思ったのでFlashのLoadVarsオブジェクトを使って通信してみることにしました(結局包むことには変わりないけど)。LoadVarsではcontent typeが'application/x-www-form-urlencoded'でBODYがfoo=val1&bar=val2baz=val3な感じのレスポンスをLoadVarsのonLoadハンドラ内で扱うことができる。
今Catslyst使って遊んでるので、Catalyst::View::JSONに以下のようなパッチを当てて、
tkoyachi:~/lib/perl tkoyachi$ diff -u Catalyst-View-JSON-0.09/lib/Catalyst/View/JSON.pm Catalyst/View/JSON.pm --- Catalyst-View-JSON-0.09/lib/Catalyst/View/JSON.pm 2006-04-20 22:17:54.000000000 +0900 +++ Catalyst/View/JSON.pm 2006-05-24 05:30:29.000000000 +0900 @@ -1,12 +1,13 @@ package Catalyst::View::JSON; use strict; -our $VERSION = '0.09'; +our $VERSION = '0.09a'; use base qw( Catalyst::View ); use Encode (); use NEXT; use Catalyst::Exception; +use URI::Escape; __PACKAGE__->mk_accessors(qw( allow_callback callback_param expose_stash encoding json_dumper )); @@ -86,17 +87,23 @@ $json = Encode::encode($encoding, $json); } - if (($c->req->user_agent || '') =~ /Opera/) { - $c->res->content_type("application/x-javascript; charset=$encoding"); - } else { - $c->res->content_type("text/javascript; charset=$encoding"); - } - my $output; $output .= "$cb(" if $cb; $output .= $json; $output .= ");" if $cb; + if ( $c->req->args->[0]->{flashvars} ) { + my $flashvars = $c->req->args->[0]->{flashvars}; + $c->res->content_type( 'application/x-www-form-urlencoded' ); + $output = $flashvars.'='.uri_escape( $output ); + } + else { + if (($c->req->user_agent || '') =~ /Opera/) { + $c->res->content_type("application/x-javascript; charset=$encoding"); + } else { + $c->res->content_type("text/javascript; charset=$encoding"); + } + } $c->res->output($output); }
以下のようにforwardする。forward時に渡してる第二引数はLoadVarsのonLoadハンドラ内でJSONパーサに渡すためのパラメタ名です。以下の場合だとflash側にはparams='{"foo":$foo_value}'がわたるはず。
$c->stash->{foo} = $foo_value; $c->forward( 'MyApp::View::JSON', [{flashvars => 'params'}] );
flash側では、
var loader:LoadVars = new LoadVars(); loader.onLoad = function( success ) { if ( success ) { var result:Object = JSON.parse( this.params ); self.log( result ); } else { self.log( "onload error." ); } } loader.load( "http://localhost:3000/get_foo" );
な感じで。