AS3:编写跨域加载的swf脚本

时间:2011-09-21 15:05:39

标签: flash actionscript-3 cross-domain

我有一些奇怪的域间加载行为。我需要让我的加载swf访问我加载的swf的类和方法跨域,但尽管我的所有applicationDomain设置和跨域设置,我不能跨域转换为可用类型,但它完全相同域。

情景:

域A上的应用程序从域B加载皮肤(实际上是大型域结构的所有部分(test.domain.co.uk,assets.domain.co.uk等),但出于Flash的目的,它们是不同的) 。目前,一些文件在测试环境中,并且在它上线之前会在几个环境中移动,所以我保持所有安全调用相对松散。遍布整个地方都有crossdomain.xml文件。

加载代码:

_skinLoader = new Loader();
addChild(_skinLoader);
var context:LoaderContext = new LoaderContext();
context.applicationDomain = new ApplicationDomain(ApplicationDomain.currentDomain);
_skinLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, skinError, false, 0, true);
_skinLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, skinLoaded);
var skinurl:String = "http://www.domainB/skins/skin.swf";
var request : URLRequest = new URLRequest(skinurl);
_skinLoader.load(request, context);

COMPLETE事件代码:

onSkinLoaded(e:Event):void{
   addChild(_skinLoader);
   _skin = e.currentTarget.content as ISkin;

   trace("SHELL: Skin loaded:"+_skin); //======== traces out null when x-domain but traces out[object SkinObject] on the same domain or in the IDE
   trace("SHELL: Skin target:"+e.currentTarget.content); //===== traces out [object SkinObject] on both
   ...............

}

因此,当皮肤与shell应用程序位于同一个域中时,它会起作用,但当它们分开时则不起作用。正如您从上面的代码中可以看出,皮肤实现了ISkin并扩展和抽象类ASkin;处理安全性我有以下作为skin类的构造函数(它是fla的基类)。

public function SkinObject(){
     Security.allowDomain(this.root.loaderInfo.loaderURL);
     super();
}

其他信息:

  • 皮肤构造函数类中的跟踪fire
  • 当我测试(e.currentTarget.content is ISkin)时,如果皮肤位于同一个域中,我会认为是真的,当我在单独的域中时,我会得到错误
  • 没有安全事件
  • 我也试过将加载器上下文设置为新的ApplicationDomain。

3 个答案:

答案 0 :(得分:2)

确定。我在一个精彩的senocular页面上找到了答案:http://www.senocular.com/flash/tutorials/contentdomains/?page=1

基本上,可以通过合并两个swfs的安全域并将applicationDomain设置为相同来克服该问题。以下是上页的引用(示例网址中有一个/以防止它们成为链接):

  

要将另一个SWF加载到您自己的安全域中,您需要使用LoaderContext对象的实例调用Loader.load。 LoaderContext的securityDomain属性设置为对当前安全域的引用。这可以通过SecurityDomain.currentDomain访问。在设置此值时,加载程序SWF表示对要加载的SWF的信任,而该SWF通过策略文件表达信任。

     

H / TTP://host.example.com/parent.swf:

trace(new LocalConnection().domain); // host.example.com

var loader:Loader = new Loader();

// create a LoaderContext that indicates that
// the loaded SWF will be loaded into this
// security domain
var context:LoaderContext = new LoaderContext(true);
context.securityDomain = SecurityDomain.currentDomain;

var url:String = "http://trusting.example.com/child.swf";
loader.load(new URLRequest(url), context);

H / TTP://trusting.example.com/crossdomain.xml:

<?xml version="1.0"?> 
<cross-domain-policy>
<allow-access-from domain="host.example.com"/>
</cross-domain-policy>

H / TTP://trusting.example.com/child.swf:

trace(new LocalConnection().domain); // host.example.com
  

使用LocalConnection实例的domain属性,将检查每个SWF的安全域。虽然子SWF源自trusting.example.com域,但它显示为在host.example.com域内,因为父SWF将其加载到自己的安全域中。

我希望这可以帮助某人花3天时间绕圈转。 谢谢senocular!

答案 1 :(得分:1)

这行代码不符合您的预期:

的Security.allowDomain(this.root.loaderInfo.loaderURL);

我很确定您从域B加载到A的swf的根URL仍然是域B,否则跨域策略系统甚至不会起作用,因为任何/所有swfs从X域加载到域将自动成为域A的子(具有此逻辑)。

您需要编写一个跨域策略文件,并将其放在域A和域B中,为域B提供明确的权限,以便与A交互,A与B交互。以下是将授予权限的跨域策略文件的示例任何人在域中加载swfs。

<?xml version="1.0" ?>
<cross-domain-policy>
<allow-access-from domain="*" />
</cross-domain-policy>

取自这个问题/答案:

Can someone post a well formed crossdomain.xml sample?

答案 2 :(得分:0)

DomainA swf: 从domainB加载swf时,从domainB加载crossdomain.xml。 如果这样做无济于事:

在DomainA上的SWF内添加:

System.allowDomain ( 'DomainB' );

crossdomain.xml基本需要图像/视频和其他类型的文件。 Swf; s需要另外照顾:

在DomainB上的SWF内添加:

System.allowDomain ( 'DomainA' );