JavaScript, ExternalInterface, Flash and Local Shared Objects

I was looking into flash’s local shared objects ( from here on LSO’s ) recently as a method of data persistence on a clients browser as the plain old HTTP cookie has its limitations.

LSO’s are like cookies and are sometimes referred to flash cookies but there are 2 main differences between them. A normal HTTP cookie can store around 4k of data, while the flash cookie can store up to 100k. Also a normal cookie is pretty easy to remove while removing a flash cookie is far more convoluted, which is a matter of some contention.

HANDY TIP: Removing LSO’s from your computer
You can remove LSO’s using a tool on Adobe site, here, which also allows you to configure your flash security settings. You can also install a Firefox plugin, Objection, which will allow you to see and remove whatever flash cookies are present on your computer.

I wanted to set a flash cookie using JavaScript. This is pretty straightforward thanks to Flash’s ExternalInterface class. This class allows you to set methods that can be accessed from an external script, like JavaScript. This class is bi-directional, so you can also call JavaScript methods from within the Flash’s ActionScript.

I used the site, viget and peachpit, to get an idea how to set this up and found some excellent, quirky tips from the schillmania site.

On my web page I needed to reference a neat SWFObject class to embed a flash player on the page. Once I had a handle on the flash player, I can call the Flash file’s ActionScript methods to request and set the LSO. The actionscript.org site has a good tutorial on how to manage LSO’s using ActionScript.

So here’s the JavaScript…

var lso_value;

function init() {
	var so = new swfobject.embedSWF("pd_check.swf", "pd_check", "1", "1", "9.0.0");
	so.write("flash_container");
}

function getFlashMovie( movieName ) {
	var isIE = navigator.appName.indexOf("Microsoft") != -1;
	return (isIE) ? window[movieName] : document[movieName];
}

function requestLSOValue() {
	getFlashMovie('pd_check').requestLSOValue();
}

function updateLSOValue( value ) {
	lso_value = value;
}

function setLSOValue( value ) {
	getFlashMovie('pd_check').setLSOValue( value );
}

… and here’s the ActionScript. You can remove the console.log lines if you wish, they were just initially helpful in knowing what was going on under the flash hood.

import flash.external.ExternalInterface;
//call from javascript
ExternalInterface.addCallback( "requestLSOValue", requestLSOValue );
ExternalInterface.addCallback( "setLSOValue", setLSOValue );

function requestLSOValue():void 
{	
	try
	{
		ExternalInterface.call('console.log', 'Trace: requestLSOValue');
		var obj_value:String = '0';
		var lso=SharedObject.getLocal("pd_check");
	
		// If name variable is not available, we assume that this is a new user
		if (lso.data.value!=null)
		{
		  obj_value = lso.data.value;
		}
		if (ExternalInterface.available) {
			ExternalInterface.call('console.log', 'Trace: getLSOValue::' + obj_value);
			ExternalInterface.call("updateLSOValue", obj_value );
		}
	}
	catch(e) {
		ExternalInterface.call('console.log', 'Flash error: '+e.toString());
	}
}

function setLSOValue( obj_value ):void 
{	
	try{
		ExternalInterface.call('console.log', 'Trace: setLSOValue');
		var writeSuccess:Boolean = false;
		// Create a shared-object named "userData"
		var lso=SharedObject.getLocal("pd_check"); 
		// Store the name
		lso.data.value=obj_value;
		var success = lso.flush();
		if (success == "pending") {
		 lso.onStatus = function(result) {
		  if (result.code == "SharedObject.Flush.Success") {
		   ExternalInterface.call('console.log', 'Trace: Sucess writing to disk');
		   writeSuccess = true;
		  } else {
		   ExternalInterface.call('console.log', 'Trace: Failure writing to disk');
		   writeSuccess = false;
		  }
		 };
		} else {
		 writeSuccess = success;
		}
	}
	catch(e) {
		ExternalInterface.call('console.log', 'Flash error: '+e.toString());
	}
}

The main thing I learned from this is, it is pretty useless as a replacement for third party cookies. This will not allow you to set cookies across domains… not that I could find anyway. So the flash movie file ( pd_check.swf ), that the flash player embed references, has to be on the same domain as the website ( where the JavaScript is trying to access the Flash ActionScript ).

Down the road, I am going to look into DOM Storage, mainly as a curiosity. I came across it in researching LSO’s and it looks very interesting. This facility is part of the HTML 5 spec so its not fully available yet, but it looks like a neat evolution of standard HTTP cookies.

UPDATE: I found a way to create cross domain or third party cookies here.

7 thoughts on “JavaScript, ExternalInterface, Flash and Local Shared Objects

    1. Hi Stephan,

      tbh, I’m not 100% sure. But from how I understand it, Flash will not permit you to use javacript on a site A to access a flash file on site B. It does appear from that article, to be possible using just flash, but I am not a flash expert. If you find a solution I’d appreciate if you let me know it, be dead handy 🙂

      Thanks for your comment.

  1. The current flash player configuration (the one hidden on the adobe web page), has a check box to deny 3rd party lsos, so I get the impression i’m doing something wrong.

  2. you need to allow thirdparty domains using

    Security.allowDomain(“foobar.com”);

    in your actionscript code; without which flash restricts such communications to same domain. In your embedded code for the flash, provide flashparam “allowscriptaccess” as “always” search on google, there are plenty of examples available.

  3. Wow…this really IS a terrific article! Thoughtful, easy to read, great links referencing related sites.

    This computer teacher from California really admires what you did here. Thumbs up and great job, Eoin. 🙂

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s