- February 16, 2009
- |
- 4 Comments
Remote content loading in AS3. Phew!
I did a little research recently when trying to figure out the ins and outs of transferring content over to a CDN. Doing this should save both load time and money, but figuring out security issues with Flash content that loads from remote, sometimes unknown locations can be frustrating. Here’s what I’ve learned:
Several things must be taken into consideration when loading content into Flash, especially from locations outside the relative path of the SWF that is loading the content. I’ve broken this down into two parts, the LOADER SWF, the SWF that is doing the loading, and the LOADED SWF, the SWF that is being loaded in from a remote location. I’m using a SWF as an example of loaded content, but with the exception of the security allowances that need to be implemented in that SWF, everything else still applies to loading in any other kind of static content.
LOADER SWF
The SWF will load it’s content using an instance of the Loader class. In the interest of security, Flash will separate loaded content to prevent it from interfering with the application that loaded it. Specific Security Domain and Application Domain settings must be set so that the loaded content can be accessed and utilized.
Security Domain
Putting the loaded content in the same security domain as the Loader (SecurityDomain.currentDomain) will allow access to the loaded content.
Application Domain
Loading content into the same application domain as the Loader (ApplicationDomain.currentDomain) is what will allow you to access public variables and methods in as loaded SWF.
More info on Flash ApplicationDomains: http://blogs.adobe.com/rgonzalez/2006/06/applicationdomain.html
example
// loader declaration
var loader:Loader = new Loader();
// loader context
var context:LoaderContext = new LoaderContext();
context.checkPolicyFile = true;
context.securityDomain = SecurityDomain.currentDomain;
context.applicationDomain = ApplicationDomain.currentDomain;
// url request
var request:URLRequest = new URLRequest('http://www.myUrl.com/myContent.swf');
// load call
loader.load(request, context);
LOADED SWF
The SWF being loaded in needs to be set up to be accessed. Do this by setting security allowances in the document class of that swf.
Security Allowances
I usually set any security allowances first thing in this constructor my document class:
example
public function MyDocClass()
{
Security.allowDomain('http://domain/main.swf');
super();
}
Get as specific as possible with the string that describes the domain that will be accessing the SWF.
Allowances in the Security class are explained more in-depth here: http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/system/Security.html#allowDomain()
Crossdomain Policy
The loading SWF is going to look for a crossdomain.xml file at the root of the domain that holds the loaded content. It’s best to comply to the most recent Policy file guidelines for the latest version of Flash player. This article explains the most recent changes: http://www.adobe.com/devnet/flashplayer/articles/fplayer9_security_02.html.
example
It is the ‘allow-access-from’ node in the crossdomain policy that the Flash SecurityDomain is going to look for when it loads the external content.
UPDATE 08/13/2009: More on this here.

Oh, Flash security issues. If you ever have to deal with loading content that comes through a redirect (like an ad…), you’ll have to check your policy twice. So if you’re grabbing stuff and you aren’t sure where it’s really coming from, you might want to implement something like the following.
This article from Steven Sacks details a basic solution to the problem:
Instead of having two onComplete handlers, I like to just use a try…catch block in the following manner:
function loadImage( url:String )
{//add your listeners and whatnot, obviously this is minimum
loader.contentLoaderInfo.addEventListener( Event.COMPLETE, handleComplete );
var context:LoaderContext = new LoaderContext( true );
loader.load( new URLRequest( url ), context );
}
function handleComplete( e:Event )
{
loader.contentLoaderInfo.removeEventListener( Event.COMPLETE, handleComplete );
try
{//attempt to use the loaded content
var image:DisplayObject = loader.content as DisplayObject;
processImage( image );
} catch( err:Error )
{//the image was actually on a different server than you initially tried to grab it from
loader.unload();
loadImage( LoaderInfo( e.target ).url );
}
}
Hmm, this article from Steven Sacks:
AS3 Security Error #2122 with 300 redirects
[...] written a little bit on remote content loading before. Steven Sacks (via Jesse Warden) has the most straightforward solution and the one that I’ve [...]
Thanks so much for this. I’ve been having issues instantiating a class from a swf off another domain, and thought it was an ApplicationDomain issue. Honestly I had never heard of SecurityDomain, and was quite relieved to see this work. Thanks!
I did notice that when testing locally, I get an error that SecurityDomain cannot run on local content, and am working around this by testing to see if the swf is on the server (with Security.sandboxType == Security.REMOTE). Is this a safe approach, or do you have a different recommendation?