AS3 - Load a Remote Image from Any URL / Domain with No Stupid Security Sandbox Errors

Issue:

You want to load an image from an unkown external URL. It works on your computer... Sandbox Security error online (and/or the annoying images just showing up as solid white feature).

By default, Flash wants a crossdomain.xml file on the server you are loading from, but let's say there is none, because it's probably not your website.  Well, then the flash player isn't going to let you take that data and do what you want with it.

Attempting to do so will give you some error similar to:

*** Security Sandbox Violation ***
SecurityDomain 'http://www.designercolin.com/temp/ispire/get_boards.php' tried to access incompatible context 'somewebsite.com/someImage_here.jpg'

Half-Solution (aka the adobe way):

According to adobe's docs you need to do a couple things to work around this (to not access this remote data directly)- bypass policy file, and don't manipulate it in any way (ahem-lame).  See the next solution if you need to access or smooth the bitmap data.

1)  Use a LoaderContext instance with checkPolicyFile=false - this will tell it not to worry about the cross-domain issue and use the loader context object as 2nd parameter in Loader.load() call

var lc:LoaderContext = new LoaderContext();
lc.checkPolicyFile = false; // bypass security sandbox / policy file - does this effect quality when scaling?

_myLoader = new Loader();
_myLoader.contentLoaderInfo.addEventListener(Event.INIT, onImageLoaded);

// load new url
_myURLRequest = new URLRequest($url);
_myLoader.load(_myURLRequest, lc);

 

2) Show the loaded image - This is where you may get the error (this is what had me pulling my hair out) 

Even with the checkPolicyFile = false set, I had to add the loader to a SPRITE (not movieclip, and not the loader content!), as this would be accessing data outside the sandbox

private function onImageLoaded($e:Event):void
{
  _innerImage = this.addChild(new Sprite());
  //_innerImage.addChild($e.currentTarget.content); // doesn't work. sandbox security error
  _innerImage.addChild(_myLoader);
}

...by doing this, you will not have accessed this image data in any way to get the error, so you can load the image data but if you need to access the bitmapdata directly (or create a movie clip apparently?), I don't think it will work.

I'm not sure exactly why adding to a Sprite() instead of MovieClip() allowed it to work for me, they both are DisplayObjects, maybe there is something in the MovieClip constructor that accesses the image data... Whatever, it's stupid that you have to do that in the first place, so why would the method make sense!  See the other / better solution below..

Quality Question- for remote image data without policy file:

What I really want to know is (for printing purposes) - using this method, since there is no access directly to the image data, when you scale the image... does it not render with smoothing / anti-aliasing?  Is it poor quality outside of native dimensions?  Or is it basically the same quality as scaling a local image within security domain?  Final conclusion is that it's better to use a proxy if the image has to be anything but native (original size/scale)...

 

Better Solution- Go Around It

Well, since flash is finicky and now has had different bugs with different flash player versions, the smart thing to do is cut your losses and just go around this issue.  A local .php file or similar service as a proxy to cross-domains URLs will do the trick and retrieve the images and flash will basically think they were hosted locally.

Then, in flash you should set up a class that will prefix URLs for you, maybe extend the URLLoader...

However you do it, you want to prefix remote URLs with your proxy URL, and pass along the intended URL something like:

http://www.YourFlashSite.com/proxy/getimage.php?url=http://someOtherWebsite.com/someImage.jpg

On creating the PHP proxy to retrieve the file.. theres a few you can find with google but i have had issues with the majority of them-

One common proxy issue with Flash is that if your progressEvent.bytesTotal is 0 (making your preloader show Infinity) it may be because your server has gzip enabled.  You can use an app like Charles to see what your http activity looks like and see if there is gzip compression on the responses... turn off gzip for your proxy file and you're golden.

16 comments (Add your own)

1. sean wrote:
also, i didn't write it... but you will of course need to define _innerImage and addChild(_innerImage) to your stage or a stage display object to see the image on screen..

Fri, September 18, 2009 @ 1:52 AM

2. Luis Cornejo wrote:
If you want access to the bitmap data you can get it by passing in the containing Sprite to like:
BitmapData.draw(_innerImage, etc, etc...)

Mon, October 5, 2009 @ 4:37 PM

3. sean wrote:
luis, when I try your approach with the remote image from the loader, it will either give me a sandbox security error or just show nothing (blank bitmap)

I ended up using a PHP proxy to hand off remote url content locally and that did the trick... no more special handling needed.

Were you able to access and smooth remote bitmap data like that without error or blank bitmap, and no cross domain XML file??

Wed, October 21, 2009 @ 2:49 PM

4. sean wrote:
oh almost forgot - You can turn off gzip with an .htaccess file - you can specifically code it for file types, 1 file, a directory, etc..

Thu, March 4, 2010 @ 12:23 AM

5. Rosario Gueli wrote:
You are a STAR! excellent JOB!
I done it, and I noticed that even if you don't add the LoaderContext into the loader.load call it works anyway.
As long as you add the entire loader into a bloody Sprite() !!!!!!!!!!!!!!!!!!

Tue, March 9, 2010 @ 11:57 AM

6. George Rosar wrote:
I'm not positive on this but I would imagine that you would have to make it a Sprite because a MovieClip can be an external .swf with external function calls too! This could raise some security issues.

Mon, May 3, 2010 @ 3:23 AM

7. ryanouyang wrote:
hey, not work:
var image:Image=new Image();
var loader:Loader=new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,function():void
{
image.source=loader.content;
});
var lc:LoaderContext=new LoaderContext(false);
loader.load(new URLRequest("http://ooxx.ooxx/06mahoro2356.jpg"),lc);Error #2044: Unhandled IOErrorEvent:. text=Error #2036: Load Never Completed.

Tue, July 13, 2010 @ 12:47 PM

8. akarso wrote:
this works for me:
var context:LoaderContext = new LoaderContext();
context.checkPolicyFile = false;
context.securityDomain = SecurityDomain.currentDomain;
context.applicationDomain = ApplicationDomain.currentDomain;


mPlaceholder1.load(new URLRequest(rssImg[0]),context);

Wed, September 22, 2010 @ 7:54 AM

9. çiçekçi wrote:
Thanks for you sharing

Tue, October 26, 2010 @ 10:31 AM

10. bruno fenzl wrote:
Hi, I found another solution, actionscript only, for this issue. The idea is to clone the loaded bytes in a bytearray, and read this byte array with another loader, Loader.readBytes().
than you can create A bitmapData object and draw the data from this second loader...
I posted a better explanation on my blog:
http://www.inklink.co.at/blog/?p=14

Sun, November 7, 2010 @ 5:43 AM

11. Pete wrote:
Remember that you put an extra load on your host this way, since the pictures are then served through it.

That may not be an issue for most, but if you wanna avoid it, try making a javascript proxy instead.

Fri, May 27, 2011 @ 6:40 PM

12. Sean P wrote:
Great points - thank you!

Fri, May 27, 2011 @ 6:55 PM

13. Lee wrote:
Goddamn I fucking hate Adobe for dumb shit like this...

Wed, October 26, 2011 @ 6:20 PM

14. Marc wrote:
This doesn't apply to AIR. It still produces an error: "Error #2044: Unhandled IOErrorEvent:. text=Error #2036: Load Never Completed."

Mon, December 19, 2011 @ 8:27 PM

15. Vicki wrote:
Your's is a point of view where real intelligence sienhs through.

Mon, January 2, 2012 @ 2:50 AM

16. Snowy wrote:
This site is like a clsasroom, except I don't hate it. lol

Mon, January 2, 2012 @ 6:41 AM

Add a New Comment

Enter the code you see below:
code
 

Comment Guidelines: No HTML is allowed. Off-topic or inappropriate comments will be edited or deleted. Thanks.