javascript 跨域解决方案之二----利用flash作为跨域工具
2015-03-26 09:11
302 查看
一般情况,编写脚本的时候都会遇到javascript跨域的情形。有用iframe的,有用jsonp的,也有用flash的,今天我也编写一个flash的插件配合js来调用跨域请求。
actionscript文件:
js脚本桥梁:
html测试文件:
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>
相关文章推荐
- AJAXCDR:利用 Flash 完美解决 JavaScript 和 AJAX 跨域 HTTP POST/GET 表单请求[原创]
- [转]AJAXCDR:利用 Flash 完美解决 JavaScript 和 AJAX 跨域 HTTP POST/GET 表单请求
- AJAXCDR:利用 Flash 完美解决 JavaScript 和 AJAX 跨域 HTTP POST/GET 表单请求
- Ajax跨域和Javascript跨域提示无权限的解决方案
- Javascript跨域和Ajax跨域解决方案(转)
- Javascript跨域和Ajax跨域解决方案
- Flex或Flash的跨域访问解决方案
- Flex或Flash的跨域访问的解决方案
- Javascript跨域访问解决方案
- Javascript跨域和Ajax跨域解决方案
- Javascript跨域和Ajax跨域解决方案(转)
- JavaScript跨域问题的解决方案
- [Flex]Flex或Flash的跨域访问的解决方案
- Flex或Flash的跨域访问解决方案
- Javascript跨域和Ajax跨域解决方案
- Javascript跨域和Ajax跨域解决方案(转)
- [Flex]Flex或Flash的跨域访问的解决方案
- 用JavaScript实现利用FLASH嵌入网页声音
- Javascript 跨域访问解决方案
- Javascript跨域访问解决方案【转帖】