【问题标题】:AS3: scripting a cross domain loaded swfAS3:编写跨域加载的 swf 脚本
【发布时间】:2011-11-22 01:25:18
【问题描述】:

我遇到了一些奇怪的域间加载行为。我需要让我的加载 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
   ...............

}

因此,当皮肤与外壳应用程序位于同一域时,它可以工作,但当它们分开时则不行。正如您从上面的代码中可以看出的,皮肤实现了 ISkin 并扩展了抽象类 ASkin;为了处理安全问题,我将以下内容作为皮肤类的构造函数(这是 fla 的基类)。

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

其他信息:

  • 皮肤构造函数类火中的跟踪
  • 如果我测试(e.currentTarget.content is ISkin),当皮肤在同一个域上时,我得到真,在不同域上时,我得到假
  • 没有安全事件
  • 我也尝试将加载程序上下文设置为新的 ApplicationDomain。

【问题讨论】:

    标签: flash actionscript-3 cross-domain


    【解决方案1】:

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

    基本上可以通过合并两个 swf 的安全域并将 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 天时间兜圈子。 谢谢你!

    【讨论】:

    • 为了明确这个问题,而不是简单地跨域加载和编写 swf 脚本;这里跨域加载的 swf 使用 与加载 swf 相同的类。子 swf 来自另一个域,这意味着 flash 不允许它具有与父级相同的类。这意味着我无法将加载的 swf 转换为它实现的接口(设计模式!)。因此合并上述安全域和应用程序域。也可以将加载的 swfs 转换为存在于系统域中的更通用的类,如对象。
    【解决方案2】:

    DomainA 瑞士法郎: 当从 domainB 加载 swf 是从 domainB 加载 crossdomain.xml。 如果这没有帮助,那么:

    DomainA 上的 SWF 内添加:

    System.allowDomain ( 'DomainB' );
    

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

    DomainB 上的 SWF 内添加:

    System.allowDomain ( 'DomainA' );
    

    【讨论】:

    • 感谢您的回复。如果您查看发布的代码和其他答案,您会发现我有一个 crossdomain.xml 和 Security.allowDomain(this.root.loaderInfo.loaderURL)。我也试过Security.allowDomain("*")我能够加载 swf,但 我无法将其转换为它实现的接口
    • 哦错过了...你试过e.currentTarget.content as ASkin吗?
    • 嗨,是的,我试过了。我现在确信问题与 ApplicationDomain 有关。我一直在追踪e.currentTarget.content is ISkin;在同一个域上我得到了真和 x 域我得到了假。如果我将加载程序上下文设置为新的 ApplicationDomain,我可以获得相同的域输出以将 false 返回到相同的语句。 所以我想问题是: 如果上面的代码不这样做,我如何从不同的安全域加载内容以表现相同的 ApplicationDomain?跨度>
    • 我查看了我是如何使用它的:context = new LoaderContext(false, ApplicationDomain.currentDomain); false 指定跳过查找策略文件,这可能是您的情况。
    【解决方案3】:

    这行代码不会像你期望的那样:

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

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

    您需要编写一个跨域策略文件并将其放置在域 A 和域 B 中,明确允许域 B 与 A 交互,以及 A 与 B 交互。这是一个将授予权限的跨域策略文件的示例给在域中加载 swf 的任何人。

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

    取自这个问题/答案:

    Can someone post a well formed crossdomain.xml sample?

    【讨论】:

    • 您好,感谢您的回复。域 B 中皮肤的构造函数中的那行代码给出:SKIN:::: You are loading from:http://test.domainA.co.uk/source/swfa.swf。我有一个 crossdomain.xml 包含这一行 &lt;allow-access-from domain="*.domainA.co.uk"/&gt;
    • 添加到其中,Security.allowDomain("*"); 没有帮助。我认为主要兴趣点是正在加载 swf - 构造函数触发 - 但它不能强制转换为 ISkin,这是它实现的接口。这让我觉得这是一个 ApplicationDomain 问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-02
    • 1970-01-01
    • 2010-12-06
    • 1970-01-01
    相关资源
    最近更新 更多