ajax的跨域一直是一个问题,在网络上流行的几种解决方法外我有了自己的解决方法。
基本思路如下:
1,js向flash发请求
2,flash请求服务器端数据(因为flash的跨域只需要在目标服务器的根目录放一个xml,而不需要写代理)
3,flash取得数据后再回调js的方法,这样就完成了一次异步请求
另外在获取服务器端数据的过程中flash可以实时将已读取的字节数通知给js,这是xmlhttprequest做不到的,也就是能实现完美的loading(有个前提,就是服务器端的xml不能是动态生成,要不只能取得已读取的字节,而取不到总字节);
as代码如下:

package ...{
import flash.display.Sprite;
import flash.events.*;
import flash.net.*;
import flash.xml.*;
import flash.system.*;
import flash.external.ExternalInterface;
import flash.utils.Dictionary;
import flash.text.TextField;
import flash.utils.Timer;
import flash.text.TextFieldType;
import flash.text.TextFieldAutoSize;
import NT.*;
import flash.utils.*;

public class AjaxHelper extends Sprite ...{


private var config_url:Object=...{

/**//*接口地址1*/

soufun:...{url:"http://xxx?",handle:xml2Obj4sf},

/**//*接口地址2*/

mapabc:...{url:"http://xxx?",handle:xml2Obj4map},

/**//*接口地址3*/
ip:"XMLFile.xml"
};
private var err:String="";//错误

public function errorOut():void ...{
ExternalInterface.call("alert",err);
}
private var cstate:Boolean=false;//状态

public function get cstateOut():Boolean ...{
return this.cstate;
}
var t1:Date;
var t2:Date;
private var output:TextField;

/**//*入口函数*/

public function AjaxHelper() ...{
flash.system.System.useCodePage=true;
t1=new Date();
initJsInterface();
//trace(Core.NetConfig)
cstate=true;

/**//*Debug*/
output = new TextField();
output.y = 0;
output.width = 400;
output.height = 200;
output.multiline = true;
output.wordWrap = true;
output.border = true;
output.text = "Initializing... ";
addChild(output);
//jsInterfaceHandle("sf",null,null);


}

/**//*初始化外部接口*/

private function initJsInterface():void ...{
var _f:Array=[
["nt_AjaxData",jsInterfaceHandle],
["nt_ErrOut",errorOut],
["nt_GetComAreaStr",jsInterfaceHandle]
];

if (ExternalInterface.available) ...{

try ...{

with (ExternalInterface) ...{

for (var i in _f) ...{
addCallback(_f[i][0], _f[i][1]);
}
}

} catch (error:SecurityError) ...{
err+="发生安全错误: " + error.message + " ";

} catch (error:Error) ...{
err+="发生错误: " + error.message + " ";
}

} else ...{
err+="容器不允许接口.";
}
}

/**//*外部接口处理函数*/

private function jsInterfaceHandle(options:Object) ...{

if (options.type in config_url) ...{
output.appendText(String(options.type)+"--type---"+options.callback);
sendHttpRequest(options);

} else ...{
}
//处理待写

}

/**//*发送请求*/

private function sendHttpRequest(options:Object):void ...{
URLLoader.prototype["options"]=new Object;
var loader:URLLoader = new URLLoader();
loader["options"]["type"]=options.type;
loader["options"]["callback"]=options.callback;
if(options.progressback)loader["options"]["progressback"]=options.progressback;
if(options.progressback)loader["options"]["errback"]=options.errback;
configureListeners(loader);
var request:URLRequest = new URLRequest(config_url[options.type].url+(options.para?options.para:"")+"&"+new Date().getTime().toString());

try ...{
loader.load(request);

} catch (error:Error) ...{
err+="无法请求.";
}
}

/**//*设置读取事件委托*/

private function configureListeners(dispatcher:IEventDispatcher):void ...{
var _e:Array=[
[Event.COMPLETE,completeHandler],
[Event.OPEN,openHandler],
[ProgressEvent.PROGRESS,progressHandler],
[SecurityErrorEvent.SECURITY_ERROR,securityErrorHandler],
[HTTPStatusEvent.HTTP_STATUS,httpStatusHandler],
[IOErrorEvent.IO_ERROR,ioErrorHandler]
];

with (dispatcher) ...{

for (var i in _e) ...{
addEventListener(_e[i][0], _e[i][1]);
}
}
}

/**//*数据读取事件委托处理函数*/

private function completeHandler(event:Event):void ...{/**//*完成*/
t2=new Date();
var dd=t2.getTime()-t1.getTime();
output.appendText(dd);
trace("时间差:"+dd);
var loader:URLLoader = URLLoader(event.target);
//trace(loader["options"]["type"]);
var newxml:XML=new XML();

try ...{
newxml=XML(loader.data.toString().replace(""","“").replace("'","‘"));//.replace(/http:///g,"")

} catch (error:Error) ...{
newxml=XML(<root>数据格式错误</root>);
}
var retobj:String=config_url[loader["options"]["type"]]["handle"](newxml);
//trace(retobj);
//output.appendText(retobj.poi[0].x);
ExternalInterface.call(loader["options"]["callback"].toString(),retobj);//回调
}

private function openHandler(event:Event):void ...{/**//*开始*/
//output.appendText("openHandler: " + event);
}


private function progressHandler(event:ProgressEvent):void ...{/**//*过程*/
var loader:URLLoader = URLLoader(event.target);
if(loader["options"]["progressback"])
ExternalInterface.call(loader["options"]["progressback"].toString(),event.bytesLoaded+"/"+event.bytesTotal);
}


private function securityErrorHandler(event:SecurityErrorEvent):void ...{/**//*安全错误*/
err+="securityErrorHandler: " + event;
var loader:URLLoader = URLLoader(event.target);
if(loader["options"]["errback"])
ExternalInterface.call(loader["options"]["errback"].toString(),err);
}


private function httpStatusHandler(event:HTTPStatusEvent):void ...{/**//*HTTP状态*/
err+="httpStatusHandler: " + event;
}


private function ioErrorHandler(event:IOErrorEvent):void ...{/**//*IO错误*/
err+="ioErrorHandler: " + event;
var loader:URLLoader = URLLoader(event.target);
if(loader["options"]["errback"])
ExternalInterface.call(loader["options"]["errback"].toString(),err);
}

/**//*xml转换为Json*/

protected function xml2Obj4sf(xml:XML):Object ...{/**//*sf*/
var _str:String="{hit:[";

for each (var element:XML in xml.hit) ...{
_str+="{";
var _t:String="";

for each (var j in element.child("*")) ...{
_t+='"'+j.name()+'":"'+j+'",';
}
_t=_t.slice(0,_t.length-1);
_str+=_t+"},";
}
if(xml.hit.length>0)
_str=_str.slice(0,_str.length-1);
_str+="]}";
return _str;
}

protected function xml2Obj4map(xml:XML):Object ...{/**//*MAPABC*/
var _str:String="{poi:[";

for each (var element:XML in xml.list.poi) ...{
_str+="{";
var _t:String="";

for each (var j in element.child("*")) ...{
_t+='"'+j.name()+'":"'+j+'",';
}
_t=_t.slice(0,_t.length-1);
_str+=_t+"},";
}
if(xml.list.poi.length>0)
_str=_str.slice(0,_str.length-1);
_str+="]}";
return _str;

}
}
}
使用as3写的,初步功能已经实现,具体效率还是有待实现
html的代码如下

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gbk" />
<title>AjaxHelper</title>

<script language="JavaScript">...

function thisMovie(movieName) ...{

if (navigator.appName.indexOf("Microsoft") != -1) ...{
return window[movieName];

} else ...{
return document[movieName];
}
}

function sendToActionScript(value) ...{
var _v=new Object();
thisMovie("AjaxHelper").nt_AjaxData(_v);
}

function ascallback (jsonStr) ...{
var kk=eval("("+jsonStr.toString()+")");
thisMovie("AjaxHelper").nt_ErrOut();

alert(kk.hit[0].title);
}

</script>
</head>
<body>
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
id="AjaxHelper" width="400" height="200"
codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab">
<param name="movie" value="AjaxHelper.swf" />
<param name="quality" value="high" />
<param name="bgcolor" value="#869ca7" />
<param name="allowScriptAccess" value="sameDomain" />
<embed src="AjaxHelper.swf" quality="high" bgcolor="#869ca7"
width="400" height="200" name="AjaxHelper" align="middle"
play="true" loop="false" quality="high" allowScriptAccess="sameDomain"
type="application/x-shockwave-flash"
pluginspage="http://www.macromedia.com/go/getflashplayer">
</embed>
</object>
<div id="outit"></div>
<form name="form1" onsubmit="return false;">
<input type="text" name="input" value="" />
<input id="qq" type="button" value="Send" onclick="sendToActionScript(this.form.input.value);" /><br />
</form>
</body>
</html>
