解决Flash在302跨域安全的Bug

2011-10-13 09:48:29

这个要转一下,好用。 在开发一个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个解决方法中第三种最优但是具备局限性,第一种适用性最广,但是麻烦。而第二种,我们可以放弃不用了!