うみの河童

Flash+JavaScriptでtwitterAPIのクロスドメインを跳ね除ける

いまさらだけど、
Flashからtwitterのつぶやきやらを引っ張ってこようとしたんだけど、
twitterAPIはひたすらクロスドメインに引っかかるということで
悩みまくった。

PHPをかませる方法も試したんだけど、
レンタルサーバにはcrossdomain.xmlを自分で置けないし、
じゃあ別ディレクトリに置けばいいじゃんってなったんだけど、
FlashPlayer10から 使えないみたいだし

ε-(ーдー)ハァ

となっていたら、twitterで
「JavaScriptで代わりに読みにいったら?」と神のお告げがあり、
調べて
どうにか
成功したのでここにまとめます。

サンプル

データもあげておきます
download

っていいながらも、いつも通り参考にさせていただいただけなんだけど(笑)

glasses factoryさん
サーバーサイドなしで twitter と Flash を連携させる

Okiraku Programmingさん
JSONPの動的取得+エラー処理

JSONPというのが
クロスドメインが発生するAPIを代わりにたたいてJSONを引っ張る仕組みみたい。

自分が作ったサンプルです。

遊んでみてくださいヽ( ´ ▽ ` )ノ

HTML

[html]<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"></span>
<pre><html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<meta charset="utf-8">
<title>twitter test</title>

<!-- swfobject -->
<script type="text/javascript" src="./js/swfobject.js"></script>
<script type="text/javascript">
var flashvars = {};

var params = {
'quality' : 'high',
'wmode' : 'window',
'allowNetworking' : 'all',
'allowScriptAccess' : 'always'
}

var attributes = {};
attributes.id = "flashContent";
attributes.name = "flashContent";
attributes.align = "middle";

swfobject.embedSWF("./swf/twitter_test.swf", "flashContent", "550", "400", "10", "./swf/expressInstall.swf", flashvars, params, attributes);
</script>

<!-- JSONP -->
<script type="text/javascript" src="./js/twitter-request-proxy.js"></script>
<script type="text/javascript">
function getJson(url)
{
//読込み後にFlash側の関数をたたく。
xds.load(url, function(result){ swfName("flashContent").getResult(result) }, function(){ swfName("flashContent").getError()});
}

//IEとその他の誤差吸収
function swfName(str)
{
if(navigator.appName.indexOf("Microsoft") != -1)
{
return window[str];
}
else
{
return document[str];
}
}
</script>

</head>
<body>
<div id="flashContent"></div>
</body>
</html>[/html]

ActionScript3.0

[as3]package
{
import flash.display.Bitmap;
import flash.display.Loader;
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.external.ExternalInterface;
import flash.net.URLRequest;
import flash.system.LoaderContext;
import flash.system.Security;
import flash.text.TextField;

/**
* ...
* @author Kurashita Masayuki
*/

public class Main extends MovieClip
{
//ログ出力用
public var logText:TextField;
//ユーザネーム出力用
public var nameText:TextField;
//ボタン
public var button:MovieClip;

//tweetをいれる
private var tweetVector:Vector.<Object>;
private var icon:Bitmap;

//--------------------------------------------------------------------------
//
// コンストラクタ
//
//--------------------------------------------------------------------------
public function Main()
{
//twitterのJSONを引っ張れた
ExternalInterface.addCallback("getResult", getResult);

//エラー
ExternalInterface.addCallback("getError", getError);

button.addEventListener(MouseEvent.CLICK, onClick);
}

private function onClick(e:MouseEvent):void
{
//すでに配置されていたら消す
if (icon != null)
{
removeChild(icon);
icon = null;
}

//ログのリセット
logText.text = "";

//初期化
tweetVector = new Vector.<Object>();

//tweetの読込み開始
tweetLoad();

}

//--------------------------------------------------------------------------
//
// tweetの読込み開始
//
//--------------------------------------------------------------------------
private function tweetLoad():void
{
if (nameText.text != "")
{
var userName:String = nameText.text;

var url:String = "http://twitter.com/statuses/user_timeline/" + userName + ".json" /*".xml?count=200"*/;

//JSにURLを渡して読みにいってもらう
ExternalInterface.call("getJson", url);
}
}

//----------------------------------
// JSONPでたたいてError
//----------------------------------
private function getError():void
{
logText.text = "JSONP ERROR";
}

//----------------------------------
// JSONPでたたいて返ってきた
//----------------------------------
private function getResult(result:Object = null):void
{
logText.text = "JSONP SUCCESS";

//tweetをLOGに表示して、Vectorに入れる
for each (var item:Object in result)
{
logText.appendText("\n" + item.text);
tweetVector.push(item);
}

//何かしらのtweetがあるなら
if (tweetVector.length != 0)
{
//アイコン画像のURLの分解
var array:Array = String(tweetVector[ 0 ].user.profile_image_url).split("normal");
//73x73のアイコン画像のパスを生成
var iconUrl:String = array[ 0 ] + "bigger" + array[ 1 ];

//アイコン画像の読込み
iconImageLoad(iconUrl);
}
}

//--------------------------------------------------------------------------
//
// アイコン画像の読込み
//
//--------------------------------------------------------------------------
private function iconImageLoad(iconUrl:String):void
{
//クロスドメイン対策
var context:LoaderContext = new LoaderContext(true);

var loader:Loader = new Loader();
var request:URLRequest = new URLRequest(iconUrl);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, iconImageLoadComplete);
loader.load(request, context);
}

//----------------------------------
// アイコン画像読込み完了
//----------------------------------
private function iconImageLoadComplete(e:Event):void
{
//アイコンの配置
icon = e.target.content as Bitmap;
addChild(icon);
}

}

}[/as3]