绕开安全沙箱跨域调用Swf中的方法.Submitted by 三七 on 2007, November 1, 10:07 AM. 互动媒体
Flash作为一个跨域跨平台的产品,可以让开发者很便利地开发出跨域的产品, 之前我使用本地通讯对象做了一个通讯平台的本地代理, 例如: 一款横向的互联网应用程序,它是实时链接到服务器的,可以通过Socket或是Rtmp等方式,那么,当用户同时找开N个网页的时候,每一个应用程序都有可能与服务器建立一个链接,而采用本地通讯对象做一个本地通讯平台的代理很具优势,它可以大大减少服务器端的负荷. 但是作为这样一个产品其安全性要求应该是比较严格的. 自从学习Flash AS以后, 之前我就发现了一个安全沙箱的问题. 今天我又发现一个,即: 绕开安全沙箱跨域调用Swf中的方法. 之前听到大伙就跨域加载位图无法访问里面的数据的问题已有解决方法,而我这里是对跨域加载异域的Swf并实例化里面的资源或是类,并调用这些类.各位看到我的代码可以去测试一下. 思路如下:
1.通过URLLoader以二进制的方式加载异域的SWF.
2.加载得到的二进制通过Loader.loadBytes()方法再加载一次. [这里并不会影响加载执行的效率,因为是在内存中进行的.]
3.然后在Loader加载成功的方法里面用: content=event.currentTarget;保存.
4.这个时候你会发现content已经是一个Loader了.而里面的contentLoaderInfo.content已经是一个MovieClip了.
5.你可以通过content.contentLoaderInfo.applicationDomain.getDefinition(name)的方式实例化里面的资源了.
Flash 本地运行库探索.
Submitted by 三七 on 2007, August 2, 10:17 PM. 互动媒体
自从AS3推出来之后,研究它已有一段时间了.AS3在本地客户端提供了两个对象
ocalConnection和SharedObject本地共享对 象.利用这两个对象可以弥补客户端浏览器Js的很多不足.而本地共享对象更具独有的性质,对每一个独立域的SWF来说默认都拥有100K的本地共享存储空 间.虽然只有100K但是可以做很多的事情了,例如可以用作跨域Cookie,或是用户参数设置的保存等.当看到这里的时候,不知道有没有人想到,可以将 这100K做成一个在本地加载的运行库? 在这里我们探索一下.
先解释一下什么叫本地运行库, 如果学过C的人都知道,C有一些库文件,后缀名为.lib,这些库文件里面存储的是已编译好的程序,包抱数据结构和功能函数,它是一个静态的库,当C编译的时候加载这些库里面已编译好的二进制数据结构或函数放到目标的程序中,这样就可以实现代码重用,加快编译速度. 在C++时代,也有类似的库,但更多使用的是后缀名为.dll的库文件,.dll的库文件跟.lib的有根本性的区别. .dll的库文件叫动态库文件, 它是指程序在执行的时候加载这个.dll文件进内存再调用里面的函数,实例它里面的类. 现在我们讨论的就是在AS3中实现类似的.dll这种文件的功能. 在用户客户端浏览器中缓存一些可动态加载并运行的库类. 当然,你也可以将Js字符串放在里面,加载运行. 呵呵,听起来是不是不可思议? 你可千万不要下载一个病毒放在这里面哦,不然我想杀毒 软件都清不了. 呵呵,说笑啦,FlashPlayer的安全沙箱不允许你缓存的这个库跨域读取或执行,所以不用担心这个.
要实现本地运行库的第一个条件成熟了,就是有地方缓存,有100K供我们使用,如果有的用户设置达1M的空间,那么,你可以缓存更多的东西,不过一般的用户不会设置这么高的. 第二个条件就是如何存取一个库到这个本地共享对象中去, 我们可以采用将swf从服务器端读取出来,然后用二进制的形式写进去, 还好AS3的URLRequest提供了一个读取二进制数据的功能,而Loader也提供了一个将二进制转化为SWF的功能. 这样,本地运行库实现起来就比较简单了.
下面讲一下我的思路:
本地运行库的目的是,将一些常用的工具类,或是一些不变的资源文件打包成一个SWF文件,带一个版本号,通过URLRequest加载成功后,缓存在本地,作为一个运行支持的库,里面的类,或是图片资源等,你要的时候就去这个库取出来就可以了.示例代码如下:
ActionScript代码
package {
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.net.SharedObject;
import flash.utils.ByteArray;
import load.LoadEvent;
import load.LoadFileBase;
import load.LoadFileData;
/**
* 完成本地共享对象的读取,版本比较,加载,替换等操作.
*/
public class LocalRunLib extends Sprite{
public const LOADFAILED:String="load_local_Lib_failed";
public const LOADSUCCESS:String="load_local_Lib_success";
private var ver:String;
public var Lib
;
public function LocalRunLib():void{
getLib("Lib.swf","0708a01"
;
addEventListener(LOADSUCCESS,testSuccess);
addEventListener(LOADFAILED,testFailed);
}
private function testSuccess(event:Event):void{
trace(event.target.Lib.applicationDomain.getDefinition("Tt"
);
}
private function testFailed(event:Event):void{
trace(event.target);
}
/**
* 获取运行库.
* @param _url 获取本地失败后,向远程加载.
* @param ver 当前需要的版本.
*/
private function getLib(_url:String,ver:String):void{
var flag:Boolean=false;
var share:SharedObject=SharedObject.getLocal("resources"
;
var Obj
bject=share.data;
this.ver=ver;
if(Obj!=null)
if(Obj.version==ver){
converToLib(Obj.lib);
flag=true;
}
share.close();
share=null;
if(!flag){
var loadFile
oadFileBase=new LoadFileBase(new LoadFileData(_url,LoadFileBase._SWF));
loadFile.addEventListener(LoadFileBase.SUCCESS,success);
loadFile.addEventListener(LoadFileBase.FAILED,failed);
}
}
/**
* 将共享对象变成可运行的库.
*/
private function _onLoaderComplete(event:Event):void{
// 下面的Lib大伙可以测试一下,是否是Loader对象了.
Lib=event.currentTarget;
event.target.removeEventListener(Event.COMPLETE, _onLoaderComplete);
dispatchEvent(new Event(LOADSUCCESS));
}
/**
* 写入到库.
*/
private function writeLocalLib(swf
,ver:String)
{
var share:SharedObject=SharedObject.getLocal("resources"
;
share.data.version=ver;
share.data.lib=swf;
share.flush();
share.close();
share=null;
}
/***
* 将二进制内容转化为可运行库.
*/
private function converToLib(data:ByteArray):void{
var loader
oader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, _onLoaderComplete);
loader.loadBytes(data);
}
/**
* 加载指定url的运行库成功.
*/
private function success(event
oadEvent):void{
converToLib(event.loadData.data as ByteArray);
writeLocalLib(event.loadData.data,ver);
removeEvent(event.target as LoadFileBase);
}
/**
* 加载指定url的运行库失败.
*/
private function failed(event
oadEvent):void{
removeEvent(event.target as LoadFileBase);
dispatchEvent(new Event(LOADFAILED));
}
/**
* 删除事件.
*/
private function removeEvent(loadFile
oadFileBase):void{
loadFile.removeEventListener(LoadFileBase.SUCCESS,success);
loadFile.removeEventListener(LoadFileBase.FAILED,failed);
}
}
}
以上代码只是一个参考,如果你想获得此段代码的话,可以给我发邮件:Wills@37studio.net

GB2312 http://ware.zhyh.org/trackback.php?id=121&encode=gb2312
UTF-8 http://ware.zhyh.org/trackback.php?id=121&encode=utf-8