解决Flash在302跨域安全的Bug

在开发一个Flash图片幻灯片程序的时候遇到当服务器出现302重定向跳转的时候,Flash Player不会自动去加载crossdomain.xml导致出现跨域安全错误,至少在网上查找相关的解决方法,总结消化了一下,可以列出以下几个方法:

1、使用try catch的方式来捕捉到错误,然后分析出错信息,然后强制让Flash Player去加载重定向地址后的crossdomain.xml

示例代码:

var loader:URLLoader = new URLLoader();

loader.contentLoaderInfo.addEventListener(Event.COMPLETE, handleComplete);

function handleComplete(e:Event):void

{

try{

var bmp:BitmapData = Bitmap(e.target.content).bitmapData;

} catch (e:Error){

var msg:String = e.msg;

//利用正则表达式匹配

var regExp:RegExp = /\ http\:\/\/([^\/]+)\//g;

if(regExp.test(msg)){

var domain:String = regExp.exec(msg)[0];

Security.loadPolicyFile([domain, "crossdomain.xml"].join(""));

//do sth.

}

}

}

这种方法是用过匹配Error的出错信息获得302之后的新URL从而加载新的跨域策略文件,给人有点Hack的感觉。

2、这种方法和上面的方法大同小异,但是要更加聪明点同时也具备一定的局限性。

示例代码:

var loader:URLLoader = new URLLoader();

loader.contentLoaderInfo.addEventListener(Event.COMPLETE, handleComplete);

function handleComplete(e:Event):void

{

try{

var bmp:BitmapData = Bitmap(e.target.content).bitmapData;

} catch (e:Error){

//通过设置loaderContext来解决问题

var loaderContext:LoaderContext = new LoaderContext(true);

loader.load(new URLRequest(Loader(e.target).contentLoaderInfo.url), loaderContext);

}

}

此方法不需要复杂的匹配就能拿到新的url表面上看起来真的挺好用。

3、具体我都无法解释为何能够解决问题,但是却很好解决了这个问题,但是依旧有点美中不足:

示例代码:

var loader:URLLoader = new URLLoader();

loader.contentLoaderInfo.addEventListener(Event.COMPLETE, handleComplete);

//直接设置LoaderContext的AD和SD

var loaderContext:LoaderContext = new LoaderContext(true, ApplicationDomain.currentDomain, SecurityDomain.currentDomain);

loader.load(new URLRequest("http://yourdomain.com/image.jpg"), loaderContext);

仅仅通过设置ApplicationDomain和SecurityDomain就能解决302的问题,这看起来比起上面提到的两种方法都要简单得多!只是这样很让人费解,如果你读完了AS的帮助文档会感到更加迷茫,上面说过这两个属性只对SWF有意义,对图片是没有意义的...

那么现在我们来分析下3种解决方法的优缺点:

表面上看第一种方法是最差的,需要恶心的正则匹配,而且需要裸露出来的try catch,这意味着至少要加载两次图像资源才能完成整个加载图片的过程。

而第二种方法实际上也要加载两次才能完成加载图片的整个过程。只是少了正则表达式,但是采用此方法还不如直接用第3种方法呢!

第三种方法明显要简单很多(此方法是cbm提供的),甚至可以不用去理解和分析代码,而且不用加载两次,并且解决了Bug。但是实际上却有着局限性,面对NetStream这一类的加载就一点办法都没有了,因为NetSteam没有提供LoaderContext的设置,这个时候就只能使用我们的第一种方法(包括第二种方法也不能,因为依靠了contentLoaderInfo)。

最后总结3个解决方法中第三种最优但是具备局限性,第一种适用性最广,但是麻烦。而第二种,我们可以放弃不用了!

loading...