javascript 跨域解决方案之二----利用flash作为跨域工具

一般情况,编写脚本的时候都会遇到javascript跨域的情形。有用iframe的,有用jsonp的,也有用flash的,今天我也编写一个flash的插件配合js来调用跨域请求。


actionscript文件:

package util
{
	/**
	 * 该类封装了相关请求的操作方法。
	 * **/
	import com.adobe.serialization.json.JSON;
	import com.adobe.serialization.json.JSONDecoder;
	import com.adobe.serialization.json.JSONEncoder;
	
	import flash.events.Event;
	import flash.events.HTTPStatusEvent;
	import flash.events.IOErrorEvent;
	import flash.events.SecurityErrorEvent;
	import flash.external.*;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.net.URLRequestMethod;
	import flash.net.URLVariables;
	
	//var jsonArray:Array = JSON.decode( URLLoader( event.target ).data );
	

	public class ReqHandler
	{
		public function ReqHandler()
		{
		}
		
		var _status_code:int=0;
		public function sendReq(url:String,method:String,paras:String,dataType:String,js_succss_func:String,js_error_func:String):void{
			var requestVars:URLVariables = new URLVariables();

			
			var request:URLRequest = new URLRequest();
			var jsonobj :Object={};
			try{
				jsonobj =  com.adobe.serialization.json.JSON.decode(paras);
			}
			catch (error:Error)
			{
				this.showError("无法将json字符串转换为json!");
				this.showError(error.toString());
				return;				
			}
			
			debug(paras);
			
			if(method.toLocaleLowerCase()=="post"){
				request.url = url;
				request.method = URLRequestMethod.POST;
				
				for(var x in jsonobj){
				requestVars[x]=jsonobj[x];
				}
				request.data = requestVars;//构造参数。
			}
			else{
				request.url = url;
				request.method = URLRequestMethod.GET;
				//--构造get参数。
				for(var x in jsonobj){
					requestVars[x]=jsonobj[x];
				}
				request.data = requestVars;//构造参数。
			}
			
			
			
			
			var loader:URLLoader = new URLLoader();
			loader.dataFormat = URLLoaderDataFormat.TEXT;
			loader.addEventListener(Event.COMPLETE, loaderCompleteHandler);
			loader.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);
			loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
			loader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
			
			try
			{
				loader.load(request);
			}
			catch (error:Error)
			{
				this.showError("无法加载url地址【"+url+"】!现在将回调js方法:"+js_error_func);
				this.showError(error.toString());
				ExternalInterface.call(js_error_func, 404,error.toString())				
			}
			
			function loaderCompleteHandler(e:Event):void
			{
				//debug(e.target.data);				
				var returndata=e.target.data;
				if(dataType.toLocaleLowerCase()=="json"){
				try{
				returndata=com.adobe.serialization.json.JSON.decode(returndata)
				}
				catch(ex:Error){
				debug("服务端返回数据格式并非标准的json格式,无法转换!");		
				debug(ex.toString());
				}
				}
				else{
				}
				
				ExternalInterface.call(js_succss_func,returndata)
				
				
				//var variables:URLVariables = new URLVariables( e.target.data );
				//if(variables.success)
				//{
					//trace(variables.path);     
				//}
			}
			function httpStatusHandler (e:Event):void
			{
				//trace("httpStatusHandler:" + e);
				_status_code=e["status"];
				return;
				debug(e.toString());
				
				
				if(e["status"]>=400){
					ExternalInterface.call(js_error_func, e["status"],"服务端错误")
				}//假如大于或等于四百,400-5xx都是错误的意思。那么执行错误方法。
				else{
				}
				//debug(e.to);
			}
			function securityErrorHandler (e:Event):void
			{
				debug("flash安全异常:"+e.toString());
				ExternalInterface.call(js_error_func,  _status_code,e.toString())
				
			}
			function ioErrorHandler(e:Event):void
			{
				//trace("ioErrorHandler: " + e);
				debug("flashIO异常:"+e.toString());
				ExternalInterface.call(js_error_func,  _status_code,e["text"])
			}
			//该代码片段来自于: http://www.sharejs.com/codes/flash/3896
		
		}
	
		public function debug(msg:String):void{
		trace(msg);	
		ExternalInterface.call("console.log", "来自flash CRF-AJAX的调试信息: "+msg);		
		}
		public function showError(msg):void{
			trace(msg);	
			ExternalInterface.call("console.log", "来自flash CRF-AJAX的错误: "+msg);				
		}
	}
}


package
{
	/**
	 * 该类负责注册调用接口,接收参数等。
	 * **/
	import flash.display.Sprite;
	
	import util.ReqHandler;
	import flash.external.*;
	import flash.events.Event;
	import flash.system.Security;
	
	public class crf_ajax extends Sprite
	{
		public function crf_ajax()
		{
			//this.testsendReq();
			
			if (stage)
			{
				
				this.init();
			}
			else
			{
				addEventListener(Event.ADDED_TO_STAGE, this.init);
			}
			
			
		}
		private function init(event:Event = null) : void
		{
			removeEventListener(Event.ADDED_TO_STAGE, this.init);  
			Security.allowDomain("*");		
			this.regInterface();
			debug("运行init方法中。");
			//testsendReq();
		
		}
		
		
		public function testsendReq():void{
		var _req:ReqHandler=new ReqHandler();
		var jsonstring='{"x":"x val","y":99,"birth":"19990-12-12 12:14:05.4","xxyy":"hello ,how are you? you should say \'okay\', no ,is that \"you mad.\"."}';
		 jsonstring='{"x":"x val","y":99,"birth":"19990-12-12 12:14:05.4","xx yy":"hello ,how are you? you should say  \'okay\'  "}';
		_req.sendReq("http://192.168.4.12:8123/getMexxdiaFileList.do","get",jsonstring,"json","alert","alert");
		}
		
		public function sendReq(url:String,method:String,paras:String,dataType:String,js_succss_func:String,js_error_func:String):void{
			var _req:ReqHandler=new ReqHandler();
			_req.sendReq(url,method,paras,dataType,js_succss_func,js_error_func);
		}
		//注册js可以使用的接口。
		private function regInterface(){
			ExternalInterface.addCallback("sendReq",  sendReq);		
		}
		public function debug(msg:String):void{
			trace(msg);	
			ExternalInterface.call("console.log", "来自flash CRF-AJAX的调试信息: "+msg);		
		}
		
	}
}

js脚本桥梁:


/**
 * 这是利用flash进行跨域的一个封装方法。
 * 值得注意的是,进行跨域的时候,主域名下面必须有
 * crossdomain.xml文件。
 * jquery,util及 swfobject都是必须的。
 */
;window.CRF_AJAX_FLASH_OBJ=null;//这是全局的crf ajax swf对象引用。
;window.CRF_AJAX_FLASH_HasInit=false;//是否已经初始化了。。。请注意,已经初始化表示已经调用init方法了,但是并不一定将swf加载完毕了。
;window.CRF_AJAX=function(swfPath,onReady){
            //--【工具】内部使用的通用方法及工具。
    var innerTools = {
        //浏览器兼容访问DOM
        getFlashMovieObject: function (movieName) {
            if (window.document[movieName]) {
                return window.document[movieName];
            }
            if (navigator.appName.indexOf("Microsoft Internet") == -1) {
                if (document.embeds && document.embeds[movieName])
                    return document.embeds[movieName];
            }
            else // if (navigator.appName.indexOf("Microsoft Internet")!=-1)
            {
                return document.getElementById(movieName);
            }
        }
    };

    var _swf_id="crf_ajax_swf";
    var _App={
         _embedFlash: function () {
             $(document.body).append("<div style='display:block; width: 0px; height: 0px; overflow: hidden; position: absolute; visibility: hidden; border: 1px solid red;'><div id='"+_swf_id+"'></div></div>");
            // For version detection, set to min. required Flash Player version, or 0 (or 0.0.0), for no version detection.
            var swfVersionStr = "11.1.0";
            // To use express install, set to playerProductInstall.swf, otherwise the empty string.
            var xiSwfUrlStr = "playerProductInstall.swf";
            var flashvars = {

            };
            var params = {};
            params.quality = "high";
            params.bgcolor = "#000000";
            //params.allowscriptaccess = "*";
             params.allowScriptAccess="*";
            params.allowfullscreen = "false";
            params.wmode="opaque";
            var attributes = {};
            attributes.id = _swf_id;
            attributes.name = _swf_id;
            attributes.align = "middle";
            swfobject.embedSWF(
                swfPath, _swf_id,
                "100%", "100%",
                swfVersionStr, xiSwfUrlStr,
                flashvars, params, attributes);
            // JavaScript enabled so display the flashContent div in case it is not replaced with a swf object.
        }
        //--检测flash状态。
        ,detectFlashStatus:function(){
                //--判断是否正常加载flash完成。


                var _____flashDonw=false;
                var ___endup=false;
                var __times=0;
                var timer_1=setInterval(function(){

                    var _flashobj=innerTools.getFlashMovieObject(_swf_id);
                    try{
                        var frames=_flashobj.TotalFrames();
                        if(frames>0){
                        window.CRF_AJAX_FLASH_OBJ=_flashobj;
                        if(onReady!=undefined){
                            onReady();
                        }
                            clearInterval(timer_1);
                            return;
                        }
                        else{

                        }

                    }
                    catch (ex){
                        console.log("is playing 无法运行。"+new Date());
                    }
                    __times+=10;
                    if(__times>=10000){
                        alert("flash文件加载时间过长,加载失败!");
                        clearInterval(timer_1);
                        ___endup=true;
                        return;
                    }
                },10);

        }
    };

    var returnObj={

        init:function(){
            if(window.CRF_AJAX_FLASH_HasInit==false){
                _App._embedFlash();
                window.CRF_AJAX_FLASH_HasInit=true;
                _App.detectFlashStatus();
            }
        }
        //--当前该flash是否已经加载完成。
        ,isOkay:function(){

            if(window.CRF_AJAX_FLASH_OBJ==null){
                return false;
            }
            return true;
        }
        //--发送请求。
        ,ajax:function(opts){

            if(window.CRF_AJAX_FLASH_OBJ==null){

                console.log("crf ajax swf 尚未加载成功.");
                return;
            }
            var settings={
                url:""
                ,data:{}
                ,dataType:"json"
                ,method:"post"
                ,success:function(serverData){

                }
                ,error:function(status,error){

                }
            };

            settings= $.extend({},settings,opts);
            //--生成唯一的回调函数用于回调。
            var _random_key=util.getRandomWords(5);
            var _func_success_name="crf_ajax_success_"+new Date().getTime()+"_"+_random_key;
            var _func_error_name="crf_ajax_error_"+new Date().getTime()+"_"+_random_key;
            window[_func_success_name] = function(serverData){
                settings.success(serverData);
            };
            window[_func_error_name] = function(status,error){
                settings.error(status,error);
            };
            var jsonstr=JSON.stringify(settings.data);
            window.CRF_AJAX_FLASH_OBJ.sendReq(settings.url,settings.method,jsonstr,settings.dataType,_func_success_name,_func_error_name);


        }


    };

    return returnObj;

};

html测试文件:

<!DOCTYPE html>
<html>
<head>
    <title></title>
<script src="/static/lib/jquery-1.11.0.min.js"></script>
    <script src="/static/lib/util.js"></script>
    <script src="/static/lib/swfobject.js"></script>
    <script src="/static/vendor/crf-ajax/crf-ajax.js"></script>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>

<script>
    $(function(){
        var _crfajax=CRF_AJAX("/static/vendor/crf-ajax/crf-ajax.swf",function(){
            _crfajax.ajax({
                url:"http://192.168.4.12:8123/getMediaFileList.do"
                ,method:"get"
                ,data:{
                    name:"max min"
                    ,gender:"no male no female"
                }
                ,dataType:"json"
                ,success:function(serverdata){
                    console.log("服务端返回的是:");
                    console.log(serverdata);
                }
                ,error:function(state_code,error){
                    console.log("state code "+state_code);
                    console.log("error "+error);
                }
            });
        });
        _crfajax.init();
        window.crf=_crfajax;
    });
</script>
</body>
</html>


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值