开发者

AS3: scripting a cross domain loaded swf

I'm having some strange inter-domain loading behaviour. I need to give my loading swf access to my loaded swf's classes and methods across domains, but despite all my applicationDomain settings and cross domain settings, I'm not being able to cast it to a usable type across domains, but开发者_如何学Go it works perfectly same domain.

The scenario:

Application on domain A loads a skin from domain B (actually all part of a massive domain structure (test.domain.co.uk, assets.domain.co.uk, etc), but for Flash's purposes they are different). Currently some of the files are on a testing environment and will move through several environments before it goes live, so I'm keeping all security calls relatively loose. There are crossdomain.xml files all over the place.

the loading code:

_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);

the COMPLETE event code:

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
   ...............

}

So it works when the skin is on the same domain as the shell application, but not when they are separate. As you may tell from the code above the skin implements ISkin and extends and abstract class ASkin; to deal with security I have the following as the constructor of the skin class (which is the base class of the fla).

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

Other info:

  • Traces in the skin constructor class fire
  • When the skin is on the same domain if I test (e.currentTarget.content is ISkin) I get true, when on separate domains, I get false
  • There are no security events
  • I have tried setting the loader context to new ApplicationDomain as well.


Ok. I've discovered the answer on one of the brilliant senocular's pages: http://www.senocular.com/flash/tutorials/contentdomains/?page=1

Essentially the problem can be overcome by merging the Security Domains of the two swfs and to set the applicationDomain to the same. Below is a quote from the above page (example urls have a / in them to prevent them becoming links):

To load another SWF into the security domain of your own, you would need to call Loader.load with an instance of a LoaderContext object. The securityDomain property of that LoaderContext is set to a reference to the current security domain. This is accessible through SecurityDomain.currentDomain. In setting this value, the loader SWF expresses trust in the SWF that is to be loaded, while that SWF expresses trust through a policy file.

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

Using the domain property of a LocalConnection instance, the security domain is checked for each SWF. Though the child SWF originated from the trusting.example.com domain, it's shown as being within the host.example.com domain because the parent SWF loaded it into its own security domain.

I hope that helps someone from spending 3 days going around and around in circles. Thank you senocular!


This line of code will not do what you expect it to:

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

I'm pretty sure that the root URL of the swf you're loading from domain B to A will still be domain B, otherwise the crossdomain policy system wouldn't even work in the first place, because any/all swfs loaded from X domain to A domain would automatically become a child of domain A (with this logic).

You need to write a crossdomain policy file and place it in both domain A and domain B giving explicit permission for domain B to interact with A, and A with B. Here is an example of a crossdomain policy file that will grant permission to anyone loading the swfs in the domain.

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

Taken from this question/answer:

Can someone post a well formed crossdomain.xml sample?


DomainA swf: When loading the swf from domainB is loading crossdomain.xml from domainB. if this will not help then:

inside SWF on DomainA add:

System.allowDomain ( 'DomainB' );

crossdomain.xml basicaly needed for images / videos and other type of files. Swf;s needs to be taked care sepparately:

inside SWF on DomainB add:

System.allowDomain ( 'DomainA' );
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜