换种方式实现Ajax的异步传输

1 篇文章 0 订阅

 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 >
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值