tohokuaikiのチラシの裏

技術的ネタとか。

jqcrossdomainをPOSTメソッドに適用できるようにしてみた

Firefox6とかChromeとかはすでにクロスドメインAjaxができるようですが、I.E待ちですよねー。

ということで、見つけたのがFlash通してやってくれるこれ
http://code.google.com/p/jqcrossdomain/

すばらしいー。と思った・・・のだけど、POSTメソッドに対応していない。

ということで、POST対応。Ajaxの呼び出しとしては

$.ajax({
    type: "post",
    url: "http://www.example.com/hoge.php",
    data: {
       d:$('#markupTextarea').val()
     },
     success: function(data, status){
        alert(data);
     }
});

みたいな、dataにObjectを使うこと前提。

ということで、
com/googlecode/jqcrossdomain/proxy/Proxy.as

package com.googlecode.jqcrossdomain.proxy {
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.HTTPStatusEvent;
	import flash.events.IOErrorEvent;
	import flash.events.SecurityErrorEvent;
	import flash.external.ExternalInterface;
	import flash.system.Security;
	import flash.net.URLRequest;
	import flash.net.URLRequestMethod;
	import flash.net.URLLoader;
	import flash.net.URLVariables;
	[SWF(backgroundColor="#ffffff",width="1",height="1",frameRate="20")]
	public class Proxy extends Sprite {
		public static const BIND_FUNCTION_NAME:String = "bindCallback";
		private var httpStatus:Object = {};
        private var req:URLRequest;
		public function Proxy() {
			Security.allowDomain(loaderInfo.parameters.host);
			addEventListener(Event.ADDED_TO_STAGE,init);
		}
		private function init(e:Event):void {
			ExternalInterface.addCallback(BIND_FUNCTION_NAME,bindCallback);
			var rf:String = loaderInfo.parameters.readyFuncName;
			if(rf) ExternalInterface.call(rf);
			removeEventListener(Event.ADDED_TO_STAGE,init);
		}
		private function bindCallback(funcname:String,s:Object):void {
			var url:String = s.url + '?' + Math.random();
			var loader:URLLoader = new URLLoader();
			if(s.policyFile) {
				Security.loadPolicyFile(s.policyFile);
			}
			loader.addEventListener(HTTPStatusEvent.HTTP_STATUS,function(e:HTTPStatusEvent):void{
				httpStatus[funcname] = e.status;
			});
			var cb:Function = function(e:Event):void{
				ExternalInterface.call(funcname,httpStatus[funcname]||200,String(loader.data));
				loader = null;
			}
			loader.addEventListener(Event.COMPLETE,cb);
			loader.addEventListener(IOErrorEvent.IO_ERROR,function(e:IOErrorEvent):void{
				httpStatus[funcname] = 404;
				cb(e);
			});
			loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR,function(e:SecurityErrorEvent):void{
				httpStatus[funcname] = 403;
				cb(e);
			});
            req = new URLRequest();
            req.method = s.type == "post" ? URLRequestMethod.POST : URLRequestMethod.GET;
            req.url = url;
            var variables:URLVariables = new URLVariables;
            if (s.data is Object){
                for (var i:* in s.data){
                    variables[i] = s.data[i];
                }
            }
            req.data = variables;
			loader.load(req);
		}
	}
}