Google analytics code

Tuesday, October 13, 2009

Flash / ActionScript 3 / Flex : Reading browser cookies

Part of an ActionScript 3 project I was working on required me to pull cookies from the users browser into Flash. I tried hunting around google to find a good method to achieve this, but found a lot of articles that wanted you to alter the embed code for flash. I wanted to find a way inside Flash to read the users cookies.

I wrote some code to do something similar in ActionScript 2 that used LoadVars. This class has been removed in ActionScript 3.

This is the ActionScript 3 code I came up with. It uses ExternalInterface to execute a bit of javascript that will pull the cookies directly into flash. It alters the cookie string to make it look like a URL and runs it through URLVariables.

package {
    import flash.display.Sprite;
    import flash.external.ExternalInterface;
    import flash.net.URLVariables;
    
    public class BrowserCookies extends Sprite
    {
        //this will parse the cookie data
        private var _urlVariables:URLVariables;
        
        /**
         * Return all the cookie values in one object
         * @return URLVariables 
         * 
         */
        public function get urlVariables() : URLVariables {
            return _urlVariables;
        }
        
        /**
         * Return one cookie value
         * @param value String
         * @return String
         * 
         */
        public function getCookieValue(value:String) : String {
            var returnValue:String = "";
            
            if(_urlVariables && _urlVariables[value]) {
                returnValue = _urlVariables[value];
            }
            
            return returnValue;
        }
        
        /**
         * This will connect to the browser and pull cookies into flash 
         */
        public function BrowserCookies() : void{
            //this will hold the data returned from javascript
            var browserCookieString:String;
            
            //pull the data from javascript
            browserCookieString = ExternalInterface.call("function(){return document.cookie}");
            
            //replace ; with & to make it look like a url
            browserCookieString = browserCookieString.replace(/;\s/g, "&");

            //parse the cookie string into variables. you can now access cookie variables as properties of this object
            if(browserCookieString) {
                _urlVariables = new URLVariables(browserCookieString);
            }
        }
    }
}


Now you can access any cookie property inside flash. Here is a quick example of how to use the class. Assume BrowserCookies.as exists in the same folder as the example class.
package
{
    import flash.display.Sprite;
    import flash.text.TextField;
    
    public class Index extends Sprite{
        public function Index(){
            //this will pull all the cookies out of the browser
            var urlVars:BrowserCookies = new BrowserCookies;
            var textField:TextField = new TextField;
            
            textField.width = 200;
            textField.height = 200;
            textField.text = urlVars.getCookieValue("today");
            
            addChild(textField);
        }
    }
}

I've uploaded a Flex Projext Export version of this example available here. Feel free to contact me if you have any questions.

14 comments:

  1. Does this work on all browsers?

    ReplyDelete
  2. There shouldn't be a browser issue. I tested the script in Chrome, Firefox and IE. I didn't test it in Opera, but if you access the cookies properties in the same way it should work fine.

    ReplyDelete
  3. awesome. thanks.

    ReplyDelete
  4. Very valuable, thanks !!!

    ReplyDelete
  5. Hi, after a lot of Google searches this appears to be exactly what I'm after for a project, however I am unable to get it to work. I get this error:

    ReferenceError: Error #1065: Variable addFrameScript is not defined.
    at BrowserCookies()

    Does this only work if you compile it using Flex or is there a method for compiling it via Flash CS4. I am quite the AS3 novice so any help/pointers will be greatly appreciated.

    ReplyDelete
  6. I'm not using the method addFrameScript in the BrowserCookies class so that shouldn't be an issue. You may want to double check your code to see if it's related to something else.

    ReplyDelete
  7. That's a great example. Thanks a lot! I think it can be done a bit shorter and simpler, like this:

    package com.flashdroid.utils
    {
    import flash.external.ExternalInterface;
    import flash.net.URLVariables;

    public var Cookies: URLVariables = new URLVariables(ExternalInterface.call("function(){return '8=); '+document.cookie}").replace(/;\s/g, "&"));
    }

    Essentially it does the same, but you can import the code and access cookies using static Cookie URLVariables object, i.e. Cookies['name']

    Works for me :)

    ReplyDelete
  8. Hi there,

    Your code is useful and should work in many cases.

    There will be a problem however, if any of the cookie values contain an "&" sign. (FaceBook does this in their FaceBook connect implementation, for example.) It will incorrectly separate the cookie value.

    Best regards.

    ReplyDelete
  9. Thanks for sharing such valuable information. Keep posting such great info for us, thanks.

    ReplyDelete
  10. Hi,why doesn't Internet Explorer allow to access document object in ActionScript. for example this code works well in all browsers but doesn't works in Internet Explorer, do you know why and know how to solve my problem? I wan't to access the cookie.
    ExternalInterface.call("eval","alert(document.cookie)");

    ReplyDelete
    Replies
    1. It should work ok in ie. It looks like you're trying to eval a alert response which won't work. Try using the example code I have and return the values through an anonymous function.

      Delete
  11. Replies
    1. Thanks for letting me know it was broken.Should be fixed now.

      Delete
  12. Perfeito ^^ VALEU!

    ReplyDelete

If you found this page useful, or you have any feedback, please leave a comment.