aboutsummaryrefslogtreecommitdiff
path: root/content/posts/2008-05-22-persistjs-cross-browser-client-side-persistent-storage-without-cookies.html
blob: d866170af24f14f00ea486061fd88cb276054f90 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
---
date: "2008-05-22T07:19:49Z"
title: 'PersistJS: Cross Browser Client-Side Persistent Storage Without Cookies'
---

<p>I just released <a href="http://pablotron.org/software/persist-js/">PersistJS</a>, a client-side JavaScript persistent storage
library.  Features include:</p>

<ul>
<li>Small (9.3k minified, 3k gzipped)</li>
<li>Standalone: Does not need any additional browser plugins or
JavaScript libraries to work on the vast majority of current
browsers.</li>
<li>Consistent: Provides a consistent, opaque API, regardless of
the browser.</li>
<li>Extensible: Custom backends can be added easily.</li>
<li>Backwards Compatible: Can fall back to flash or cookies if no
client-side storage solution for the given browser is available.</li>
<li>Forwards Compatible: Supports the upcoming versions of Internet
Explorer, Firefox, and Safari (Opera too, if you have Flash).</li>
<li>Unobtrusive: Capability testing rather than browser detection, so
newer standards-compliant browsers will automatically be supported.</li>
</ul>

<p>If you already know why this is awesome, then you can skip
<a href="http://pablotron.org/files/persist-js-0.1.0.tar.gz">straight to the download</a>.  If you're scratching your head,
then read on...</p>

<h2>Why This is Awesome</h2>

<p>Why use PersistJS?  What's the problem with using cookies directly or
simply requiring Flash?</p>

<p>Currently the only reliable cross-platform and cross-browser mechanism
for storing data on the client side are cookies.  Unfortunately, using
cookies to store persistent data has several problems:</p>

<ul>
<li>Size: Cookies are limited to about 4 kilobytes in size.</li>
<li>Bandwidth: Cookies are sent along with every HTTP transaction.</li>
<li>Complexity: Cookies are difficult to manipulate correctly.</li>
</ul>

<p>Modern web browsers have addressed these issues by adding non-Cookie
mechanisms for saving client-side persistent data.  Each of these
solutions are simpler to use than cookies, can store far more data, and
are not transmitted along with HTTP requests.  Unfortunately, each
browser has addressed the problem in a different and incompatible way.
There are currently 4 different client side persistent data solutions:</p>

<ul>
<li>globalStorage: Firefox 2.0+, Internet Explorer 8</li>
<li>localStorage: development WebKit</li>
<li>openDatabase: Safari 3.1+</li>
<li>userdata behavior: Internet Explorer 5.5+</li>
</ul>

<p>Some developers have attempted to address the client side storage
issue with the following browser plugins:</p>

<ul>
<li>Adobe Flash</li>
<li>Google Gears</li>
</ul>

<p>The problem with relying on plugins, of course, is that users without
the plugin installed miss out on the feature in question, and your
application is dependent on software from a particular vendor.  Google
Gears, for example, is not widely deployed.  Flash is, but it has
problems of its own:</p>

<ul>
<li>Many users block Flash or require a click in order to enable
flash content; this makes Flash unsuitable as a transparent,
client-side data store.</li>
<li>Flash is notoriously unreliable on newer 64-bit machines.</li>
<li>Some businesses block Flash content as a security measure.</li>
</ul>

<p>Anyway, if we include Gears and Flash, that means there are no less than
6 incompatible solutions for storing client-side persistent data.  </p>

<p>The most notable attempt at addressing this problem is probably <a href="http://dojotoolkit.org/offline">Dojo
Storage</a>.  Unfortunately, Dojo Storage does not support Internet Explorer
without Flash, and it does not support Safari or other WebKit-based
browsers at all (at least, not without Flash).  Also, Dojo Storage is
not standalone; it requires a several other Dojo components in order to
operate.</p>

<p>PersistJS addresses all of the issues above.  It currently supports
persistent client-side storage through the following backends:</p>

<ul>
<li>flash:         Flash 8 persistent storage.</li>
<li>gears:         Google Gears-based persistent storage.</li>
<li>localstorage:  HTML5 draft storage.</li>
<li>whatwg_db:     HTML5 draft database storage.</li>
<li>globalstorage: HTML5 draft storage (old spec).</li>
<li>ie:            Internet Explorer userdata behaviors.</li>
<li>cookie:        Cookie-based persistent storage.</li>
</ul>

<p>Each backend exploses the exact same interface, which means you don't
have to know or care which backend is being used.</p>

<h2>Examples</h2>

<p>Here are some simple examples of PersistJS in use:</p>

<pre class="code"><code>// create a new client-side persistent data store
var store = new Persist.Store('My Data Store');

// pretend data
var data = "pretend this is really long data that won't fit in a cookie";

// save data in store
store.set('saved_data', data);
</code></pre>

<p>That's all there is to creating a persistent store and adding some data
to it.  Fetching data back from the store uses a callback function (to
support asyncronous backends), but it's still pretty simple to use:</p>

<pre class="code"><code>// get data back from store, and prompt user with it
store.get('saved_data', function(ok, val) {
  if (ok)
    alert('saved data = ' + val);
});
</code></pre>

<p>Removing data is pretty easy too:</p>

<pre class="code"><code>// remove data from store
store.remove('saved_data');
</code></pre>

<p>Although it isn't necessary, you can also get some information about the
detected backend using the <code>Persist.type</code> and <code>Persist.size</code> attributes:</p>

<pre class="code"><code>// build alert message
var info = [
  'Backend: ',
  Persist.type || 'none',
  ', ',
  'Approximate Size Limit: ',
  (Persist.size &lt; 0) ? 'unknown' : Persist.size 
].join('');

// prompt user with information
alert(info);
</code></pre>

<p>Finally, if you don't want a particular backend used under any
circumstances, you can disable it using the <code>Persist.remove()</code> function:</p>

<pre class="code"><code>// never use cookies for persistent storage
Persist.remove('cookie');
</code></pre>

<h2>Download</h2>

<p>This is the initial release, so there are bound to be some bugs.
PersistJS has been tested with FireFox 2.0, FireFox 3.0rc1, IE7, and
Safari 3.1.  The Gears and Flash backends work where Gears and Flash 8
are supported.  </p>

<p>The most notable omission here is IE6; it <em>should</em> work, but I don't
have IE6 handy at the moment (<a href="http://tredosoft.com/Multiple&#95;IE">MultipleIEs</a> is temporarily busted).</p>

<ul>
<li><a href="http://pablotron.org/files/persist-js-0.1.0.tar.gz">Download PersistJS 0.1.0 Tarball</a> (<a href="http://pablotron.org/files/persist-js-0.1.0.tar.gz.asc">Signature</a>)</li>
<li><a href="http://hg.pablotron.org/persist-js">PersistJS Mercurial Repository</a></li>
</ul>

<p>Commenting is still busted around here, so any comments should sent via
email or posted on <a href="http://reddit.com/info/6kd4i/comments/">the Reddit thread</a>.</p>