2008
08.06

Why use server-side data storage, if you don’t do any data processing on server? There are many cases when you’d rather keep your data structures on the client side. In Inshaker, we had to manipulate and persist large amounts of user-specific data on the client side. Cookies were not an option because of the 4kb limit. So we used the persistency library by Ilya Kantor with slight modifications. It makes use of window.globalStorage object in Mozilla, userData behavior in MSIE and Flash storage in other cases (we will be implementing Safari sqlite storage too). All three mechanisms are different: flash storage is loaded asynchronously and userData values can’t be accessed in other paths (i.e. /page.html and /dir/otherpage.html won’t be sharing the same data). That’s why we use a “proxy” page, which is loaded in an iframe. The data we persist is “attached” to an element in this page.

Usage is rather simple:


	// needs callback because it's asynchronous in case of flash
	Storage.init(function(){
		Storage.put("js", "cool language");
		var desc = Storage.get("js");
		Storage.remove("js");
		Storage.put("objc", "pretty too");
		alert(Storage.get("objc"));
		Storage.clear();
	});


Get the library from Ilya’s site. If you need cross-directory storage sharing for IE, replace his Storage.userData section with this snippet:


Storage.userData = function(onready) {
    var namespace = "data";

    if (!document.body.addBehavior) {
        throw new Error("No addBehavior available");
    }

	var e = document.createElement("iframe");
	e.setAttribute('id', 'storageFrame');
	e.style.border = '0';
	e.style.width  = '0';
	e.style.height = '0';
	var iframe = document.body.appendChild(e);
	iframe.src='proxy.html';

	iframe.addEventListener('load', function(e){
		var storage = iframe.contentWindow.document.getElementById('storageElement');
		storage.load(namespace);

	    Storage = {
	        get: function(key) {
	            return storage.getAttribute(key);
	        },

	        put: function(key, value) {
	            storage.setAttribute(key, value);
	            storage.save(namespace);
	        },

	        remove: function(key) {
	            storage.removeAttribute(key);
	            storage.save(namespace);
	        },

	        clear: function() {
	            var attrs = storage.XMLDocument.documentElement.attributes;

	            for(var i = 0; i < attrs.length; i++) storage.removeAttribute(attrs[i].name);
	            storage.save(namespace);
	        },

	        getKeys: function() {
	            var res = [];
	            var attrs = storage.XMLDocument.documentElement.attributes;

	            for(var i = 0; i < attrs.length; i++) res.push(attrs[i].name);
	            return res;
	        }
	    }
	    onready();
	}, false);
};

proxy.html is very simple:


<html>
<head>
	<title>userData proxy object</title>
</head>
<body>
	<span id=\"storageElement\" style=\"behavior:url(\'#default#userData\')\"></span>
</body>
</html>

No Comment.

Add Your Comment