JavaScript library and .swf for cross-domain flash cookies
July 13th, 2010 By nFriedly
I’m working on a project that has a legitimate (non-spammy) reason to need cross-domain cookies, and we settled on flash as a good way to accomplish this.
However, I was surprisingly unable to find any complete library or how-to guide for connecting flash cookies to javascript. So I dusted off my flash skills and built one, and and now you get to enjoy the fruit of my labor:
Download the .swf, .js, and source code from github
This is an .swf file that communicates with JavaScript via flash’s ExternalInerface to read and write to a Local SharedObject (LSO). Essentially, it’s cross-domain cookies for javascript.
It also includes an (optional) javascript library that handles embedding, communication, error checking, and logging.
The project is hosted at github: http://github.com/nfriedly/Javascript-Flash-Cookies
You might also be interested in How Facebook Sets and uses cross-Domain cookies
Working Example
See https://nfriedly.com/stuff/swfstore-example/ and http://nfriedly.github.com/Javascript-Flash-Cookies/ for a working example.
Quick start guide
To use the library, upload the storage.swf & swfstore.js files to your web server and put this HTML and JavaScript into your web page(s):
The HTML
<!-- This example uses jquery, but SwfStore does not require jquery to work. --> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> <script src="/PATH/TO/swfstore.js"></script> <input id="dataInput" /> <input id="saveBtn" type="submit" value="Save" /> <div id="status"></div>
And The JavaScript
// wait until the page has finished loading before starting
$(function(){
// first disable things while the swfStore is initializing
$('input').attr("disabled","disabled");
$('#status').text('Loading...');
var mySwfStore = new SwfStore({
// Optional but recommended. Try to choose something unique.
namespace: 'myExample',
// To work cross-domain, only one of your sites should have the
// .swf, all other sites should load it from the first one
swf_url: 'http://site.com/PATH/TO/storage.swf',
// Logs messages to the console if available, a div at the
// bottom of the page otherwise.
debug: true,
onready: function(){
// Now that the swfStore was loaded successfully, re-enable
$('input').removeAttr("disabled");
// Read the existing value (if any)
$('#dataInput').val(mySwfStore.get('myKey'));
// Set up an onclick handler to save the text to the
// swfStore whenever the Save button is clicked
$('#saveBtn').click(function(){
mySwfStore.set('myKey', $('#dataInput').val() );
$('#status').text('Saved!')
});
$('#status').text('Loaded');
},
onerror: function(){
// In case we had an error. (The most common cause is that
// the user disabled flash cookies.)
$('#status').text('Error');
}
});
});
Cross-domain usage
A copy of storage.swf located on one domain may be embedded on pages from one or more other domains, allowing cross-domain cookie access.
Troubleshooting
- Be sure the urls to the .swf file and .js file are both correct.
- If the .swf file is unable to communicate with the JavaScript, it will display log messages on the flash object. If debug is enabled, this this should be visible on the page.
- To hide the flash object and disable the log messages appending to the bottom of the page, set debug to false. (Log messages are added to a div if no console is found).
- If the user does not have flash installed, the onerror function will be called after a (configurable) 10 second timeout. You may want to use a library such as Flash Detect to check for this more quickly. Flash Player 9.0.31.0 or newer is required.
- If you pass a non-string data as the key or value, things may break. Your best bet is to use strings and/or use JSON to encode objects as strings.
- If you see the error “uncaught exception: Error in Actionscript. Use a try/catch block to find error.”, try using “//” in the .swf URL rather than “https://”. See https://github.com/nfriedly/Javascript-Flash-Cookies/issues/14 for more information.
- Do not set
display:noneon the swf or any of it’s parent elements, this will cause the file to not render and the timeout will be fired. Disable debug and it will be rendered off screen. - The error
this.swf.set is not a functionhas been known to occur when the FlashFirebug plugin is enabled in Firefox / Firebug..
Patches
Although my JS is solid, my Flash / ActionScript skills leave something to be desired. Patches to either are more than welcome at github (preferred), or just leave a comment here if you’re not sure how to use github. (This comment has a short walk through to using github.)
Production Use
If you’re using SwfStore in a production site, feel free to leave a comment here with a link to the site. I turned off WP’s default rel=”nofollow”, so enjoy the link juice
Reciprocal links are not required, but are always appreciated.


Hi, thanks for the code. One thing though, I cannot get this to work across different domains. I am getting an error when I try to save an object…
debug (swf): Error…Could not write SharedObject to disk – Error #2130
My Flash configuration allows 3rd party cookies.
Any idea why this happening?
Does it work on a single domain?
What version of flash/operating system/browser are you using?
The issue could be that there is actually a file permissions problem.
[edited]
According to the last comment on this page, that error can also happen if flash has exceeded the 100k storage limit for the domain. I would assume that it’s the domain the .swf is hosted on, but I don’t know that for sure. https://www.mochimedia.com/community/forum/topic/actionscript-help-error-2130-unable-to-flush-sharedobject_
Sorry, I had global storage settings set to none. All seems to be working now, thanks.
Gotcha, glad its working for you!
Thank you for the hard work and the article nFriedly, this has been super useful to me in my recent front-end development work.
I do have one question however. Which version of Flash is required for your storage.swf to operate properly? It would be outrageously fantastic if you knew the detailed version information (such as major, minor, and revision version).
Also, do you really recommend Flash Detect over the Adobe Flash Player Detection Kit? Have you tested both for comparison? I’m trying to decide which would be a more efficient and surefire method of detecting whether or not Flash is installed, and if so what version is installed.
The library is written in ActionScript 3.0, so it requires Flash 9 at a minimum. I did a quick scan of Adobe’s documentation and I think
anything from Flash Player 9.0.0.0 or newer would be sufficient.[ 9.0.31.0 - see next comment]I have only worked with Flash Detect, so I’m couldn’t say which is best. My guess is that either one would work fine.
Correction: I just found that Flash Player for Linux did not support ExternalInterface until version 9.0.31.0, so that is the minimum version to the best of my knowledge.
Thanks for the quick reply. That would be major version 9, minor version 0, and revision 31… right? I’m not too familiar with the versioning structure used by Adobe. Having a bit of trouble looking it up too.
I guess I’m going to test out Adobe’s Flash Player Detection Kit. I’ll report back if I have any significant troubles with it so that you/we can be better informed about the differences between it and Flash Detect.
Yes, from looking at the source code of the Adobe Flash Detection Kit, it looks like you need major 9, minor 0, and revision 31. The last number seems like it gets completely ignored.
Again, thank you for the quick reply. I’ve got another question regarding the clear method. I see in your AS that I should be able to access it using clear( key ) in my JS but I couldn’t find an example where you’ve done this. All other methods aree working (get and set) but for some reason I can’t get the clear method to actually remove the LSO cookie. Any help on that matter would be much appreciated!
Wait, scratch my last question: I think the clear function works, it just doesn’t seem to actually delete the LSO data until the browser itself has been closed. Is this normal/intended?
Hi again, I am seeing an issue in Internet Explorer 8. It appears to work fine initially in IE, but then after a few minutes, in the console, I see…
LOG: SwfStore – example: Timeout reached, assuming the store.swf failed to load and firing the onerror callback. (undefined): undefined
I see your example application has the same problem.
Any idea whats causing it? Thanks…
@dilkROM
I made a new issue, I’ll investigate that when I get a chance: http://github.com/nfriedly/Javascript-Flash-Cookies/issues/issue/8
@Eoin
I’m not seeing that; what OS are you using and what version of flash player do you have? Also, is it 64-bit?
The JS sets a timeout to detect if flash player never loads, then it clears the timeout once it receives a confirmation that the .swf loaded.
Before / after that error happens, are you able to read and write to the .swf?
@Eoin As soon as I posted that it happened to me. :/
I made a new issue: http://github.com/nfriedly/Javascript-Flash-Cookies/issues/issue/10
I’ll get that fixed as soon as possible, but It might be a few days. Feel free try and fix it yourself (and send me the code
if you need it right away.
@nFriedly, I wouldn’t mind helping to take care of the new issue myself, is there a way you can ‘invite’ me to login and make changes?
Hi dilkROM, that’s why I like git & github; you don’t need me to do anything for you to be able to make changes. Here’s a quick rundown:
1. Create an account on http://github.com
2. Set up the SSH keys and Git on your computer. http://help.github.com/ has some guides for this. Git and SSH are more difficult on windows, ask me if you need help.
3. Fork my project. (This creates a new copy on github’s servers that you own.) Then “clone” it to your computer. Cloning is like downloading, but it remembers that it’s linked to the server, so changes you make can be sent back to the server. Here’s a guide: http://help.github.com/forking/
4. Make your changes on your computer, then commit them to your local git (4a) and push them to github (4b).
4a. “Committing” saves the changes to git on your local computer.
Run the commands:
git add .
git commit -m “Short message describing the changes you made.”‘
Do this as often as you like, at a minimum every time you do something important.
4b. “Pushing” uploads the changes from git on your computer to git on github’s servers. Run the command: git push origin master
I usually do this every time I make a local commit, but some people do it less often. (In general, it’s a good idea to at least test your changes before you do this.)
5. After you’re happy with your changes and you’ve pushed them to your github account, send me a pull request. I’ll receive the request and be able to import your changes into my copy of the project on my account. This is the first time I actually get involved. http://help.github.com/pull-requests/
[Edited for clarity]
(This is the preferred way of doing things, but if you can’t figure it out then just make the changes and email me a .zip file
@nFriedly, sounds great and easy enough. I’ll see about making the changes once I get some down time at work this week. I appreciate your clear and constant communication, and all the guidance you’re providing me; it’s very helpful!
Op, I edited my last comment to make a couple of things more clear that I had skipped over.
(Oh, and you’re welcome
Hi again, about the version that I should be looking for on the client machine. You say 9.0.31, but didn’t externalinterface come out in version 8? Just wondering how you worked out the minimum version?
Thanks.
The library is written in ActionScript 3.0, which was introduced in flash 9.0.0, but the Linux version didn’t have ExternalInterface until 9.0.31
More Info: http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/external/ExternalInterface.html
Ok I think I understand now. I read this – http://www.adobe.com/devnet/flash/articles/external_interface.html and saw that ExternalInterface is available in version 8 but Actionscript 3.0 (which the library is written in) is not available until version 9.
Thanks for the clarification.
[...] Well, as I was editing my simple library, I came across a gem of a Javascript library that is better written and was open sourced. The library can be found on the site, nfriedly.com. [...]
BTW, I just committed a couple of updates to the logger. I had a bug where if you had debug mode enabled, but did not have a console such as the one provided by Firebug, the JS would hit an error in the fallback logger and never finish initializing. Unfortunately this was breaking the demo for many people.
Now if you do not have a console, the fallback logger works and appends all of the log messages to a div it creates at the bottom of the page.
I also found a bug in flashplayer that can delete the the flashcookies if you open both demo pages in separate tabs, save something in one, then refresh the other. I added a note explaining this bug, but have not yet worked around it.
@Eoin I just fixed the bug where the timeout error would fire in IE even when it loaded successfully – if the .swf is cached, IE runs the onload callback in JS *immediately* – even before JS has finished initializing. So I fixed JS to catch this and force the onload callback to wait until it has finished initializing.
I also bumped the default timeout down to 10 seconds from 60, because I think that is entirely reasonable or even a bit on the high side still. We use 3 seconds at my company.
Quick update: v1.2 has just been released:
* I added a workaround for the flashplayer bug where cookies could sometimes get deleted by a refresh.
* I also tweaked logging slightly and updated the examples.
Download the latest version from github: http://github.com/nfriedly/Javascript-Flash-Cookies/zipball/master
Very cool. And extremely usefull. Thanks
Nice job!
You should update the source code
Storage.as
———-
private function getAllValues():Object {
return dataStrore.data;
}
dataStore instead of dataStrore … just a small hint.
Thanks, and good catch – there was another bug in JS that went along with it :/
Fixed in version 1.3; updated github & the demo.
That was fast
BTW: any reason why the “clear” function is not implemented in the js file?
I’ve noticed that in a popup the swf file makes the content “larger”. Had to spend some time to figure out that in Firefox or Chrome the flash div shouldn’t be
d.style.top = “0px”;
I’ve change it to
d.style.top = “-1000px”;
and the scrollbars disappears.
Thanks
I just spent a little more time patching things up and rolled it into a 1.4 release:
* I added a .clear(key) function to the JS
* set the div.style.top to -2000px
* fixed namespacing in the SWF (NOTE: this will loose old data unless you change your namespace to the default “SwfStore” that it was using reguardless)
…and a few more little things you can check the readme for if you’re interested.
That is great. Can you add SSL support too? When I set a flash cookie on a https website, I can not read the values on a http website.
Security.allowInsecureDomain(“*”);
Done. I also left a note in the readme that users should try to limit the domains and compile a custom, more secure .swf if possible.
As always, everything is on github: https://github.com/nfriedly/Javascript-Flash-Cookies
Thanks for the feedback, let me know once your site is live.
Where is your donation button? I love to pay a small amount over PayPal for your work. Not much because I am a poor guy from Vietnam. But it helps me a lot to learn about JS and Flash Actionscript
No donation button, although I do appreciate the thought
Update: I have been persuaded to accept donations. There is now a GitTip button in the sidebar. I still appreciate the thought
Code contributions and links back to my site, however are greatly appreciated.
I have to say not only is this a quality piece of code but Nathan’s a quality guy to boot!
Thanks for the help.
For whatever its worth, we at yousoft (shameless plug: http://www.yousoft.co.uk) use it for one of our clients.
Specifically they require users to use a cool piece of javascript that scrapes content from sites and creates wish lists (great for weddings, birthdays etc).
Thanks to Nathan users don’t have to log in every time they view another page
Great work!!
It’s partially working in Opera (checked in v11.10).
The script can create the flash object but it can’t get the value: swfStore.get(key) returns ‘undefined’.
I have tried to debug the script (using Opera Dragonfly) but the browser crash when I look at the ‘swf’ object.
Any ideas?
BTW: Awesome piece of code, well written and commented!!
I’m not sure… It works for me in Opera 11.5 / OS X 10.6.8 / Flash 10,3,181,34 debug. What versions / OS are you running? (Flash player version is here: http://kb2.adobe.com/cps/155/tn_15507.html)
That page also tells whether or not it has Local File I/O Enabled. I’m not positive, but I think that’s a requirement. Is it enabled on your system?
I’m moving soon, so I really can’t jump on this right away. If you want to dig into it more without me though, you’re more than welcome to. If you come up with anything, definitely let me know. I know there’s a debug version of flash player at http://www.adobe.com/support/flashplayer/downloads.html, but I don’t know a lot about working with it.
Thanks for the compliments
Hi Nathan,
Thanks for putting this together. In the readme you mention “It would be wise to edit and recompile the flash file to limit itself to your domain and http/https settings.” Where do you fix this?
Looking at Storage.as, would it be this?
Security.allowDomain(“*”);
For example, to only allow your domain, would you just edit the value to something like:
Security.allowDomain(“http://nfriedly.com/”);
If so, how does that work with sub-domains, or even with www? Thanks for your help!
Hi Vader,
You’re close, it would actually be just the domain part, so in my case:
Security.allowDomain(“nfriedly.com”);
Or, to support multiple domains / subdomains, I believe you would have to do:
Security.allowDomain(“nfriedly.com”, “www.nfriedly.com”);
And then if you want the file to be accessible across http/https boundaries (where the .swf is https but the page is http or vice versa), you also need to do the same with:
Security.allowInsecureDomain(“nfriedly.com”, “www.nfriedly.com”);
You can find more details here:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/system/Security.html#allowDomain%28%29
Awesome! Thanks for the quick response!
No problem. I just added some additional comments to the ActionScript file to clarify things there also.
Just updated Flash player to latest debugger version on Mac (11.2.202.235) and I’m getting a JS error in Firefox. Strangely, it was fine before and still works fine in Chrome. FF console error is:
this.swf.set is not a function
swfstore.min.js:Line 27
Seems to be when it tries to set the __flashBugFix key?
I think chrome has it’s own built-in flashplayer, so that could explain the discrepancy there… But I can’t seem to reproduce the error in my system.
I just installed http://fpdownload.macromedia.com/pub/flashplayer/updaters/11/flashplayer_11_plugin_debug.dmg from http://www.adobe.com/support/flashplayer/downloads.html and http://www.adobe.com/software/flash/about/ confirms that I’m on 11,2,202,235.
I’m in FF 12.0 if that makes a difference.
You’re probably right that it’s the __flashBugFix is when the bug first appears, but I’m not sure what the root cause is. Could you send me an email with the url of the page? nathan @ [this site].com