<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Jens Arps &#187; client-side storage</title>
	<atom:link href="http://jensarps.de/tag/client-side-storage/feed/" rel="self" type="application/rss+xml" />
	<link>http://jensarps.de</link>
	<description></description>
	<lastBuildDate>Tue, 07 Sep 2010 14:11:57 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Storage Research &#8211; Your Help is Needed!</title>
		<link>http://jensarps.de/2010/09/07/storage-research-your-help-is-needed/</link>
		<comments>http://jensarps.de/2010/09/07/storage-research-your-help-is-needed/#comments</comments>
		<pubDate>Tue, 07 Sep 2010 14:11:01 +0000</pubDate>
		<dc:creator>Jens Arps</dc:creator>
				<category><![CDATA[Experiments in Web]]></category>
		<category><![CDATA[Storage]]></category>
		<category><![CDATA[client-side storage]]></category>
		<category><![CDATA[localStorage]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[persistence]]></category>
		<category><![CDATA[sqlite]]></category>

		<guid isPermaLink="false">http://jensarps.de/?p=278</guid>
		<description><![CDATA[Right now, I&#8217;m doing some research regarding client-side storage on mobile devices. But for that, I need your help!
Please grab all phones you have and navigate to http://jensarps.de/tests/storage-tests/.
There are four tiny tests there. Please do them all and report your results for each phone. If you like, include your twitter handle so I can say ]]></description>
			<content:encoded><![CDATA[<p>Right now, I&#8217;m doing some research regarding client-side storage on mobile devices. But for that, I need your help!</p>
<p>Please grab all phones you have and navigate to <a href="http://jensarps.de/tests/storage-tests/" target="_blank">http://jensarps.de/tests/storage-tests/</a>.</p>
<p>There are four tiny tests there. Please do them all and report your results for each phone. If you like, include your twitter handle so I can say thank you!</p>
<p>Your help is greatly appreciated!! Thanks a ton!!</p>
]]></content:encoded>
			<wfw:commentRss>http://jensarps.de/2010/09/07/storage-research-your-help-is-needed/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>localStorage Performance Test Results</title>
		<link>http://jensarps.de/2010/09/07/localstorage-performance-test-results/</link>
		<comments>http://jensarps.de/2010/09/07/localstorage-performance-test-results/#comments</comments>
		<pubDate>Tue, 07 Sep 2010 11:17:50 +0000</pubDate>
		<dc:creator>Jens Arps</dc:creator>
				<category><![CDATA[Experiments in Web]]></category>
		<category><![CDATA[Storage]]></category>
		<category><![CDATA[client-side storage]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[localStorage]]></category>
		<category><![CDATA[persistence]]></category>

		<guid isPermaLink="false">http://jensarps.de/?p=260</guid>
		<description><![CDATA[It&#8217;s been some time since I last updated this blog, mostly because there&#8217;s plenty going on these days. However, there&#8217;s something I&#8217;ve been wanting to publish for quite some time now: The results of the localStorage performance tests I ran several weeks ago. As I am currently working on performance tests for Mozilla&#8217;s IndexedDB implementation, ]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been some time since I last updated this blog, mostly because there&#8217;s plenty going on these days. However, there&#8217;s something I&#8217;ve been wanting to publish for quite some time now: The results of the localStorage performance tests I ran several weeks ago. As I am currently working on performance tests for Mozilla&#8217;s IndexedDB implementation, which is available in latest Minefield releases, I got reminded that there are still other results to publish – so, here we go:</p>
<p><span id="more-260"></span></p>
<p>Among other tests, the main thing I wanted to know is how long does it take to read or write 1000 entries from/to localStorage. The keys were of the form &#8220;key000&#8243;, the values &#8220;val000&#8243;, with increasing numbers. So the tests were using minimal data – only 6  bytes – but the results are still useful to get an idea of how it goes – and how the browsers perform compared to each other.</p>
<p><strong>Desktop</strong></p>
<p>All test were run on a Mac Mini. Opera and IE were tested on a virtual machine, so there might be an additional performance penalty based on virtualization. However, here are the numbers (average time needed to run the respective method 1000 times):</p>
<p>Safari 4:<br />
- getItem: 1.4ms<br />
- setItem: 1.7ms<br />
- key: 0.8ms</p>
<p>Chrome:<br />
- getItem: 240ms<br />
- setIem: 280ms<br />
- key: 230ms</p>
<p>Firefox:<br />
- getItem: 77ms<br />
- setItem: 2100ms<br />
- key: 25ms</p>
<p>Opera:<br />
- getItem: 19ms<br />
- setItem: 20ms<br />
- key: 18ms</p>
<p>IE8:<br />
- getItem: 5ms<br />
- setItem: 72ms<br />
- key: 3.6ms</p>
<p><strong>Mobile</strong></p>
<p>As we can see, Safari is lightening fast. That made me want to run the tests on a mobile phone that has a modern Safari browser. I took an HTC Desire, wich comes with Android 2.1, and thus has a Safari capable of localStorage. Here are the results:</p>
<p>HTC Desire:<br />
- getItem: 16.4ms<br />
- setItem: 19.5ms<br />
- key: 8.7ms</p>
<p>This is pretty amazing, considering that it is a phone. It still beats most of the browseres on the desktop.</p>
<p>If I find that test page again (uh, yeah, it&#8217;s lost somehow), I&#8217;ll run the tests again with newer browser releases and publish the link here, so you can run the tests yourself.</p>
]]></content:encoded>
			<wfw:commentRss>http://jensarps.de/2010/09/07/localstorage-performance-test-results/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Encrypted client-side storage with dojo</title>
		<link>http://jensarps.de/2010/04/15/encrypted-client-side-storage-with-dojo/</link>
		<comments>http://jensarps.de/2010/04/15/encrypted-client-side-storage-with-dojo/#comments</comments>
		<pubDate>Thu, 15 Apr 2010 21:48:54 +0000</pubDate>
		<dc:creator>Jens Arps</dc:creator>
				<category><![CDATA[Dojo Love]]></category>
		<category><![CDATA[Experiments in Web]]></category>
		<category><![CDATA[Goodies to go]]></category>
		<category><![CDATA[Storage]]></category>
		<category><![CDATA[client-side storage]]></category>
		<category><![CDATA[dojo]]></category>
		<category><![CDATA[dojox]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[localStorage]]></category>

		<guid isPermaLink="false">http://jensarps.de/?p=248</guid>
		<description><![CDATA[A couple of days ago, Nicholas Zakas wrote an article about secure client side storage. I think the scenario he mentioned (working from a cyber cafe) is not unsafe by nature, and could be well handled by an application. Nonetheless, client side storage such as localStorage still is subject to DNS spoofing attacks (which is ]]></description>
			<content:encoded><![CDATA[<p>A couple of days ago, <a href="http://www.twitter.com/slicknet/" target="_blank">Nicholas Zakas</a> wrote <a href="http://www.nczonline.net/blog/2010/04/13/towards-more-secure-client-side-data-storage/" target="_blank">an article</a> about secure client side storage. I think the scenario he mentioned (working from a cyber cafe) is not unsafe by nature, and could be well handled by an application. Nonetheless, client side storage such as <code>localStorage</code> still is subject to DNS spoofing attacks (which is the main security issue, I think). To handle this, one needs to encrypt the keys and values in the store.</p>
<p>So here you go: <code>dojox.storage.encrypted</code>, a <a href="http://en.wikipedia.org/wiki/Blowfish_%28cipher%29" target="_blank">Blowfish</a> encrypted storage. It sits on top of <code>dojox.storage</code>, and you get all the dojo storage manager goodness, mainly the automatic selection of the best storage provider available. It exposes the complete API that <code>dojox.storage</code> does. If an attacker gains access to the storage area, he can still nuke the storage, but the data found within will be useless.<br />
<span id="more-248"></span><br />
I&#8217;m not completely happy with it&#8217;s architecture, and I didn&#8217;t have the time yet to fully test it with all providers, but it works pretty well with <code>localStorage</code> and the performance is not too bad. If you have a spare minute and are interested, feel free to to test it yourself (ah I know, you don&#8217;t have the time yourself, but I&#8217;d be thankful!)…</p>
<h2>Usage</h2>
<p>Just use it as you would use dojox.storage, except that you need to set your passphrase before you start working with the storage:</p>
<pre>dojo.require("dojox.storage.encrypted");
var sto = dojox.storage.encrypted;
sto.setPassphrase("my super secret passphrase");
sto.put('key','value');
var value = sto.get('key');</pre>
<p>It uses/requires <code>dojox.encoding.crypto.Blowfish</code> but that&#8217;s been in dojo for ages, so no worries.</p>
<p>To use it, just put the <code>encrypted.js</code> file in your dojox/storage directory.</p>
<h2>Files</h2>
<p><a href="http://jensarps.de/tests/dojo_tests/dojo-release-1.4.0-src/dojox/storage/encrypted.js" target="_blank">the code (encrypted.js)</a><br />
<a href="http://jensarps.de/tests/dojo_tests/dojo-release-1.4.0-src/dojox/storage/tests/test_enc_storage.html">the test page</a></p>
]]></content:encoded>
			<wfw:commentRss>http://jensarps.de/2010/04/15/encrypted-client-side-storage-with-dojo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Don&#8217;t use Cookies</title>
		<link>http://jensarps.de/2010/04/10/dont-use-cookies-use-localstorage/</link>
		<comments>http://jensarps.de/2010/04/10/dont-use-cookies-use-localstorage/#comments</comments>
		<pubDate>Sat, 10 Apr 2010 17:54:01 +0000</pubDate>
		<dc:creator>Jens Arps</dc:creator>
				<category><![CDATA[Browser Struggle]]></category>
		<category><![CDATA[How to]]></category>
		<category><![CDATA[Storage]]></category>
		<category><![CDATA[client-side storage]]></category>
		<category><![CDATA[cookies]]></category>
		<category><![CDATA[localStorage]]></category>
		<category><![CDATA[persistence]]></category>

		<guid isPermaLink="false">http://jensarps.de/?p=216</guid>
		<description><![CDATA[– or: How to persist data in the 21st century.
The common way to persist data on the client side – application state, offline data, whatever –  still is to use cookies. But times have changed, and so have browsers, and there are better ways to do it today.
But why are cookies that bad? Well, here ]]></description>
			<content:encoded><![CDATA[<p>– or: <strong>How to persist data in the 21st century</strong>.</p>
<p>The common way to persist data on the client side – application state, offline data, whatever –  still is to use cookies. But times have changed, and so have browsers, and there are better ways to do it today.</p>
<p>But why are cookies that bad? Well, here are the top three reasons:</p>
<ol>
<li>Of all client side storage mechanisms, cookies have the worst limitation in size (4k if you want to stay IE-safe)</li>
<li>Cookies are sent to the server on every requests that matches the cookie domain – inlcuding XHR calls (aka. <em>How to slow down your AJAX app</em>)</li>
<li>Cookies perform bad, can be easily disabled, and, oh well, they are sooo 1995…</li>
</ol>
<p>What else to use? There are several options, let&#8217;s start with the best:<br />
<span id="more-216"></span></p>
<h2><strong>localStorage</strong></h2>
<p>This is the storage mechanism proposed by the HTML5 draft. It offers you a fast, reliable key-value store with a whopping 5M (!!) of storage space. And here&#8217;s the kicker: It&#8217;s implemented in all current major browser releases. That is, FF, Safari, Opera, IE and Chrome/Chromium. Yes, you name it, all of them, the full list. To read more about localStorage, check the <a href="http://dev.w3.org/html5/webstorage/" target="_blank">HTML5 draft</a>. But here&#8217;s all you need to know in short:</p>
<p><strong>Storage Methods</strong></p>
<p>To test if the user agent supports localStorage, just test for the existence of <code>window.localStorage</code>. Working with the storage object is trivial:</p>
<p>Setting a value:</p>
<pre>localStorage.setItem('key','value');</pre>
<p>Though the draft says the user agent should write a &#8220;structured clone&#8221; of the value to store, don&#8217;t think that you can store objects – you can only store strings. To store objects, you need to convert them to JSON before.</p>
<p>To retrieve a value, there are two options. First, you can get a value by it&#8217;s key:</p>
<pre>var value = localStorage.getItem('key');</pre>
<p>The user agent will return the value for the key, or, if it doesn&#8217;t find a matching record, <code>null</code>. Also, you can retrieve a key by it&#8217;s index:</p>
<pre>var value = localStorage.key(n);</pre>
<p>The storage object has a <code>length</code> property, and n is a number between zero and length-1. You do not get the index of a value when inserting it, but you can use the <code>key()</code> method when iterating over all items in the store using the <code>length</code> attribute.</p>
<p>There is another method to retrieve a value, but as this not documented (at least I didn&#8217;t find anything about it), I do not recommend it:</p>
<pre>var value = localStorage.key;</pre>
<p>Deleting an item:</p>
<pre>localStorage.removeItem('key');</pre>
<p>Deleting the whole storage:</p>
<pre>localStorage.clear();</pre>
<p>This clears only the storage objects of the same storage area. That is, storage objects of the current domain.</p>
<p>So far, everything is pretty trivial, but let&#8217;s look at</p>
<p><strong>Storage Exceptions</strong></p>
<p>When accessing the storage object, a user agent may raise an <code>SECURITY_ERR</code> exception – but I have never managed to trigger one. When setting an item, a user agent may raise an <code>QUOTA_EXCEEDED_ERR</code> exception. This is not only for the case when storage space is at it&#8217;s limit, but may be raised for other reasons as well. Again, I have never managed to trigger it, but it may be wise to wrap a <code>setItem</code> call in a try/catch block.</p>
<p><strong>Storage Event</strong></p>
<p>Now things get tricky, and the different browsers have different (if any) implementations. Ok, first, the theory: methods that modify the storage object (<code>setItem()</code>,<code>removeItem()</code>,<code>clear()</code>) do not report if – or when – the changes are in effect. To get notified about this, you need to connect to the storage event:</p>
<pre>window.addEventListener("storage", function(evt){
    // a change to the storage object has been attempted.
}, false);</pre>
<p>The event should have the following attributes:</p>
<ul>
<li>key</li>
<li>oldValue</li>
<li>newValue</li>
<li>url (the address of document object whose storage object was modified)</li>
<li>storageArea (the affected storage object)</li>
</ul>
<p>With this information, you can easily determine to what change the storage event belongs. But, alas, that event is not fully implemented everywhere. Here&#8217;s what I found out:</p>
<p><strong>FF 3.6.3 </strong>lets you connect to the event, and fires it according to the draft. But it does not contain *any* of the fields mentioned above.</p>
<p><strong>Safari 4.0.5</strong> lets you connect to the event, and fires it according to the draft. It&#8217;s event contains all attributes except url.</p>
<p>on <strong>Chrome 5 &amp; Chromium</strong> I couldn&#8217;t connect to the event at all or it wouldn&#8217;t let my execute code in my callback function – I have no idea if it&#8217;s even fired.</p>
<p>Latest <strong>WebKit nightly</strong> wouldn&#8217;t report anything to me, like  Chrome.</p>
<p><strong>Opera 10 </strong>lets you connect to the event, fires it accordingly, and the event contains all attributes (woot!)</p>
<p><strong>IE 8</strong> didn&#8217;t report anything back to me, too.</p>
<p>I used <a href="http://www.jensarps.de/tests/storage.html" target="_blank">this simple test file</a> to check for the event. Feel free to test other browsers and report what you found!</p>
<h2><strong>Other options</strong></h2>
<p>If the browser is too old to have localStorage, there are still other options to persist data: Firefox 2 had globalStorage, which behaves similar to localStorage. IE has userData beahvior since version 5.5. Safari has it&#8217;s built-in Sqlite database, but I don&#8217;t know since when. Plus, there&#8217;s also plugin-based storage via Flash or Gears. Only if they all fail, you should get back to cookies.</p>
<p>Of course, it would be a lot of work to write wrappers for all these storage mechanisms – but, hey, you don&#8217;t have to, others have already done it. There are several toolkits that do the work for you, and I will present three of them.</p>
<p><strong>Dojo</strong></p>
<p>The dojo toolkit has dojox.storage. It currently offers support for Flash, Gears and globalStorage. But with the files you can grab at my <a href="http://jensarps.de/2010/01/04/persistent-local-storage-with-dojo/" target="_blank">previous post on storage</a>, you gain access to localStorage, userData behavior and cookies. Working with dojox.storage is pretty simple, and you don&#8217;t have to worry about anything: dojo&#8217;s storage manager will pick the best available provider. Here&#8217;s a simple example:</p>
<pre>dojo.require("dojox.storage");
dojox.storage.put('key','value');
var value = dojox.storage.get('key');</pre>
<p>That&#8217;s it. Simple as that. You do have more options, though; you can also specify a namespace for your keys – so you can simulate working with different &#8220;tables&#8221; in one store. You can also specify a callback function for the <code>put()</code> method, to get notified when the changes are in effect and if the change was successful.</p>
<p><strong>Lawnchair</strong></p>
<p>Lawnchair has been created by <a href="http://twitter.com/brianleroux" target="_blank">Brian Leroux</a> from Nitobi. Working with it is dead simple, too. It supports localStorage, userData behavior, Gears, Webkit&#8217;s Sqlite and Cookies. It works more like a document store (you can save an object w/o specifying a key, for example), but you can also use it like a straight key/value store. In opposition to dojo&#8217;s storage system, Lawnchair works completely asnc, so you have to pass a callback function to a get() method to retrieve a value (being async is not a drawback, and it is neccessary to work with WebKit&#8217;s Sqlite). You can find some docs <a href="http://brianleroux.github.com/lawnchair/" target="_blank">here</a> and get it over <a href="http://github.com/brianleroux/lawnchair" target="_blank">at Github</a>.</p>
<p><strong>Persist.js</strong></p>
<p>Persist.js has support for localStorage, globalStorage, Gears, Flash, userData behavior and Cookies. It also works completely async. You can get it <a href="http://github.com/lloyd/persist-js" target="_blank">at Github</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://jensarps.de/2010/04/10/dont-use-cookies-use-localstorage/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>persistent local storage with dojo</title>
		<link>http://jensarps.de/2010/01/04/persistent-local-storage-with-dojo/</link>
		<comments>http://jensarps.de/2010/01/04/persistent-local-storage-with-dojo/#comments</comments>
		<pubDate>Mon, 04 Jan 2010 21:46:40 +0000</pubDate>
		<dc:creator>Jens Arps</dc:creator>
				<category><![CDATA[Dojo Love]]></category>
		<category><![CDATA[Experiments in Web]]></category>
		<category><![CDATA[Goodies to go]]></category>
		<category><![CDATA[Storage]]></category>
		<category><![CDATA[client-side storage]]></category>
		<category><![CDATA[dojo]]></category>
		<category><![CDATA[dojox]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[local]]></category>
		<category><![CDATA[localStorage]]></category>
		<category><![CDATA[persistence]]></category>

		<guid isPermaLink="false">http://jensarps.de/?p=140</guid>
		<description><![CDATA[Last year, Brian Leroux&#8217;s Lawnchair caught my interest – it is an easy and fast way to access local persistant local storage.
Uh, persistant local storage?
Ahm, yeah, in case you don&#8217;t know, that means a client-side storage, be it in a browser, or in an Air app. It&#8217;s not very popular, but that concept has been ]]></description>
			<content:encoded><![CDATA[<p>Last year, <a href="http://twitter.com/brianleroux" target="_blank">Brian Leroux</a>&#8217;s <a href="http://brianleroux.github.com/lawnchair/" target="_blank">Lawnchair</a> caught my interest – it is an easy and fast way to access local persistant local storage.</p>
<p><strong>Uh, persistant local storage?</strong></p>
<p>Ahm, yeah, in case you don&#8217;t know, that means a client-side storage, be it in a browser, or in an Air app. It&#8217;s not very popular, but that concept has been around for a long time. So why local? There are two major reasons for it: First, we need this for apps and tools that work offline – and apps and tools that work online but need an offline backup and sync later. <a href="http://twitter.com/kriszyp" target="_blank">Kris Zyp</a> wrote a <a href="http://www.sitepen.com/blog/2008/09/23/effortless-offline-with-offlinerest/" target="_blank">post about the JsonRestStore and OfflineRest</a> back in 2008, he goes a little into detail there. Secondly, we need it for apps and tools that rely on persistence for other reasons, no matter if online or offline – like it happended to me. When I ran into Lawnchair, I had the idea to build a tool that was monitoring CSS selector usage on websites and apps (you know how you sometimes lose control about CSS selectors in webapps…). To achieve this, I needed to store data locally, and persistent.<br />
<span id="more-140"></span><br />
<strong>What dojo offers<br />
</strong></p>
<p>As I was using dojo&#8217;s excellent CSSRuleStore to find out what selectors where used, I wanted to switch from Lawnchair to a dojo solution. Dojo has dojox.storage (the above mentioned OfflineRest uses dojox.storage), which provides wrappers for the following backends: Gears, Flash, globalStorage and Adobe Air (globalStorage is Firefox&#8217;s early implementation of the early WhatWG storage draft). Hm. Not that much. Gears and Flash are 3rd party solutions, globalStorage is a Firefox-only-thingy (and old, though it&#8217;s still supported in current Versions) and Air is non-browser. That means: No IE without plugins. No Safari when Flash is not available.</p>
<p><strong>What dojo does not offer (but should)</strong></p>
<p>Guaranteed, reliable support for *any* browser. Without depending on 3rd party plugins. As of now, to have this, you&#8217;d need to use Lawnchair or <a href="http://github.com/lloyd/persist-js" target="_blank">persist,js</a>, which is pretty complete. Speaking of it, let me quote from it&#8217;s readme (it&#8217;s a good read on local persistent storage in general):</p>
<blockquote><p>The most notable attempt at addressing this problem [storing client-side persistent data] is probably Dojo Storage.  Unfortunately, Dojo Storage does not support Internet Explorer without Flash, and it does not support Safari or other WebKit-based<br />
browsers at all (at least, not without Flash).  Also, Dojo Storage is<br />
not standalone; it requires a several other Dojo components in order to<br />
operate.</p></blockquote>
<p>Whoa, even other JS tools mention the lack of support in dojo…</p>
<p><strong>New providers</strong></p>
<p>Attached to this post are wrappers for the following mechanisms:</p>
<ul>
<li>localStorage: this is the current spec, and it is supported by IE8, Firefox 3, Safari 4, Opera 10, Chrome 5.</li>
<li>userData behavior: this is Microsofts client-side storage for IE &lt; 8.</li>
<li>cookie: worst case fallback solution…</li>
</ul>
<p>With these three, there&#8217;s an almost 100% coverage of browser situations (see storage overview). There are still no-go scenarios, of course, such as IE7 with userData disabled and cookies disabled, but there&#8217;s no way to address them all.</p>
<p><strong>Notes on BehaviorStorageProvider</strong></p>
<p>This one uses the <a href="http://msdn.microsoft.com/en-us/library/ms531424%28VS.85%29.aspx" target="_blank">userData behavior</a>, present in IE from version 5 up. It works with DOM elements that have a special behavior assigned. You can then use  set/get/removeAttribute() methods to store data. It has some limitations though – of course…</p>
<ul>
<li>Maximum size varies from 64k to 1M – depending on the zone the site is in. So, you can&#8217;t rely on more than 64k.</li>
<li>UserData can be switched off in security settings.</li>
<li>I couldn&#8217;t find a way to read out stored keys if you don&#8217;t know them. Maybe this is some security thingy or just a bug – but it means that some methods in the provider don&#8217;t work. (that is, getNamespaces, getKeys and clear). To work around this, we have to take some of the precious storage space and store the keys and namespaces seperately.</li>
</ul>
<p><strong>Usage</strong></p>
<p>Copy the the providers into your <code>/dojox/storage</code> directory and add the needed <code>dojo.require</code>s to <code>/dojox/storage/_common.js</code>:</p>
<pre>dojo.require("dojox.storage.LocalStorageProvider");
dojo.require("dojox.storage.GearsStorageProvider");
dojo.require("dojox.storage.BehaviorStorageProvider");
//&gt;&gt;excludeStart("offlineProfileExclude", kwArgs.dojoxStorageBuildOption == "offline");
dojo.require("dojox.storage.WhatWGStorageProvider");
dojo.require("dojox.storage.FlashStorageProvider");
//&gt;&gt;excludeEnd("offlineProfileExclude");
dojo.require("dojox.storage.CookieStorageProvider");</pre>
<p><strong>What&#8217;s left?</strong></p>
<p>Well, it would be pretty cool to have a dojo.data API compliant store that uses dojox.storage as backend, so that you could write your apps using dojo.data calls and have a reliable offline backup. I started working on that, but then came Christmas, parents, vacation, new year and a lot of beer. But hey, it&#8217;s 2010 now, and there&#8217;s plenty of time left!</p>
<p><strong>Storage Overview</strong><br />
<!-- .overviewTable td {font-size: 10px; padding:2px 5px;} --></p>
<table class="overviewTable" border="0">
<tbody>
<tr>
<td>IE 6 / IE7</td>
<td>BehaviorStorageProvider<br />
FlashStorageProvider<br />
GearsStorageProvider<br />
CookieStorageProvider</td>
</tr>
<tr>
<td>IE 8</td>
<td>LocalStorageProvider<br />
GearsStorageProvider<br />
FlashStorageProvider<br />
CookieStorageProvider</td>
</tr>
<tr>
<td>Safari 3</td>
<td>FlashStorageProvider<br />
CookieStorageProvider</td>
</tr>
<tr>
<td>Safari 4</td>
<td>LocalStorageProvider<br />
FlashStorageProvider<br />
CookieStorageProvider</td>
</tr>
<tr>
<td>Chrome 5</td>
<td>LocalStorageProvider<br />
FlashStorageProvider<br />
CookieStorageProvider</td>
</tr>
<tr>
<td>Firefox 2</td>
<td>WhatWGStorageProvider (= globalStorage)<br />
GearsStorageProvider<br />
FlashStorageProvider<br />
CookieStorageProvider</td>
</tr>
<tr>
<td>Firefox 3</td>
<td>LocalStorageProvider<br />
GearsStorageProvider<br />
FlashStorageProvider<br />
CookieStorageProvider</td>
</tr>
<tr>
<td>Opera 10</td>
<td>LocalStorageProvider<br />
FlashStorageProvider (?)<br />
CookieStorageProvider</td>
</tr>
</tbody>
</table>
<p><strong>Files</strong></p>
<p><a href="http://jensarps.de/tests/dojo_tests/dojo-release-1.4.0-src/dojox/storage/LocalStorageProvider.js" target="_blank">LocalStorageProvider.js</a><br />
<a href="http://jensarps.de/tests/dojo_tests/dojo-release-1.4.0-src/dojox/storage/BehaviorStorageProvider.js" target="_blank">BehaviorStorageProvider.js</a><br />
<a href="http://jensarps.de/tests/dojo_tests/dojo-release-1.4.0-src/dojox/storage/CookieStorageProvider.js" target="_blank">CookieStorageProvider.js</a><br />
<a href="http://jensarps.de/tests/dojo_tests/dojo-release-1.4.0-src/dojox/storage/tests/test_storage.html" target="_blank">Storage Test Page</a></p>
]]></content:encoded>
			<wfw:commentRss>http://jensarps.de/2010/01/04/persistent-local-storage-with-dojo/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>
