Serializing Javascript Objects into Cookies

A while ago I mentioned that my school gives students and faculty Novel NetDrive accounts. This means we can all publish simple websites on their service, but get no server side scripting. This makes that space great for teaching students HTML but relatively useless for everything else.

O previously described how to get a semi-presentable website constricted without server side includes. This is a sort of follow up to that article showing you more tricks. The big issue you get working in a client-side only environment is persistence. The only way to accomplish it is to use cookies. So I set out to see what exactly can I store in a cookie.

It turns out I can store just about anything in there. For example the code below generates a Javascript object with few fields and functions, and then stores it in a cookie:

<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="jquery.cookie.js"></script>
<script type="text/javascript">
	$(document).ready(function() {
 
		var obj = new Object();
		obj.a = "foo";
		obj.b = "bar";
		obj.ab = function(){return this.a+this.b;};
		obj.show = function(){alert(this.ab());};
 
		var src = obj.toSource();
 
		$.cookie("testcookie", src);
 
		temp = $.cookie("testcookie");
 
		nobj = eval(temp);
		nobj.show();
	});
</script>

The toSource function does most of the work here. It serializes an object into a string which can be then deserialized using the eval function. Note that this will work on stand alone functions too, since in Javascript they are first class objects. Neat, eh?

I’m using Klaus’ Hartl’s jQuery cookie plugin because the native Javascript handling of cookies is it is retarded and error prone. It basically returns all the cookies you set as a single string containing semi-colon separated list. As you can imagine, retrieving serialized objects which are bound to contain lots of semi-colons can be problematic. Klaus’s code was not designed for this sort of thing but it uses the encodeURIComponent method to escape special characters. Which works out great because it escapes the ‘;’ character inside of the serialized objects making them easy to retrieve.

I probably don’t need to tell you that the example above is a very, very bad coding practice. You really don’t want to eval any code that might have been tampered with. Since we are storing our object in a cookie which can then be modified on the client machine, we are really opening ourselves for abuse. So while storing functions inside cookies is possible, I would not recommend it.

What you want to do is to serialize your objects into JSON, and the safely parse it back while making sure you are actually getting back JSON object rather than random code. There is a really good plugin that does this for you. So your code will look something like this:

<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="jquery.cookie.js"></script>
<script type="text/javascript" src="jquery.json.js"></script>
<script type="text/javascript">
	$(document).ready(function() {
 
		var obj = new Object();
		obj.a = "foo";
		obj.b = "bar";
 
		var src = $.compactJSON(obj);
 
		$.cookie("testcookie", src);
		temp = $.cookie("testcookie");
 
		nobj = $.secureEvalJSON(temp);
		alert(nobj.a + nobj.b);
 
	});
</script>

The secureEvalJSON method is much safer than just running eval on arbitrary code. The pluging also has an “unsafe” eval version, but I would not recommend using it unless you can guarantee the cookies haven’t been tampered with (and in most cases you can’t).

There is a small caveat you need to keep in mind. The space you have to work in is very limited. Fore example, IE only allows you to store around 4KB of data per domain. This is not per cookie, but a total space you have for all your name-value cookie pairs. This means that sticking a huge JSON object (or many smaller ones) into a cookie just won’t work. IE will silently drop cookies that exceed this limit. So use this technique sparingly, and if you can, compress the data as tightly as possible.

This entry was posted in programming and tagged , . Bookmark the permalink.



3 Responses to Serializing Javascript Objects into Cookies

  1. El Guapo UNITED STATES Google Chrome Windows says:

    Good job thanks

    Reply  |  Quote
  2. Nico ROMANIA Mozilla Firefox Windows says:

    Very usefull indeed. Thanks!

    Reply  |  Quote
  3. Luke Scalf UNITED STATES Mozilla Firefox Mac OS says:

    Great article. The JSON and Cookie plugins are very handy. One thing to watch out for in your first code sample though. The toSource() javascript function is only available to Gecko based browsers (Firefox) and will not work in IE or Safari.

    Reply  |  Quote

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>