您的位置:首页 > Web前端 > JavaScript

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

2015-03-26 09:11 302 查看
一般情况,编写脚本的时候都会遇到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>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: