HTML5 sessionStorage for "every" browsersA Web Storage is HTML5 response to cookies limits. While the world is moving forward improving users experience and web potentiality via constantly updated browsers like Chrome, Firefox, or Safari, some Jurassic user or company could be still stuck at the origins with obsolete, deprecated, slow, and loads of bugs, browsers. The aim of this project is to bring at least one of the Web Storage in latter typology of user, or company, in a way that should simply work with a focused eye about security.
Introducing The sessionStorage ObjectThere are basically two types of Web Storage so far, and these are the localStorage, and the sessionStorage. The main difference is that the localStorage persists over different tabs or windows, and even if we close the browser, accordingly with the domain security policy and user choices about quota limit. The antagonist is the sessionStorage object which follows this rule:
When a new HTMLDocument is created, the user agent must check to see if the document's top-level browsing context has allocated a session storage area for that document's origin. If it has not, a new storage area for that document's origin must be created.
Each Document object must have a separate object for its Window's sessionStorage attribute.
In few words, the sessionStorage object does not persist if we close the tab (top-level browsing context) as it does not exists if we surf via another tab or window. As summary, as soon as we are in our tab the session storage allows us to save a large amount of key/value pairs and lots of text, something impossible to do via cookie. This is what my implementation is trying to do with browsers that do not implement this special object. If you have doubts, you can directly test the demo link, and come back whenever you want.
How Does This Implementation WorkNowadays, there is not such thing: every browser, and this is the reason I put quotes in this page title. On the other hands, there are different "de facto standards", like innerHTML and others. One of these de-facto standards is the behavior of the window name property, something I've played with since ages, but never before that concretely useful! window.name is an always present string, usually completely ignored by 99% of developers, but with below features:
as a string, it has no official length limit, except our RAM one. It could contain different megabytes of data without affecting performances it persists in the same tab, being the origin of the context, and in every page surfed inside the tab, so it could be extremely unsafe to trust it for important data it is automatically cleaned as soon as we close the tab or the browser, so used RAM will be automatically cleaned and without scripting effort Thanks to these features, I have been able to think about a string protocol able to make window.name a sort of linear storage
The Used Protocol To Save Data Linear String Storage Protocol Specs
c = special separator char
s = key prefix char
key = key to use as value reference
len = unescaped key length
value = value to store
length = value length
entry = c + s + key + c + c + length + c + value
cs key cc length c value
o.[ ]oo[ ]o[ ]
key must be a string
value must be a string
both key or value, if not strings, should be converted
both key and value cannot contain the special "c" char (replacement)
entry can always be appended into the linear string storage
entry cannot exist, or there could be more than an entry
if a key was already present, its entry has to be removed and the new one appendedThe reason I chose to save the length of the value, rather than look for the next special char at the end of the value is:
rather than a char to char check to understand where is the next special char we simply retrieve N characters/bytes, as is for example in PHP serialized strings since an entry is always appended there could be no special characters at the end of the value if I used another special char to close the entry, it would not be possible to have zero length key or zero length value ( could be both empty key and empty value here)
As summary, thanks to this simple and fast protocol, I can easily and safely save any unique key/value pair I need without having massive bottlenecks for hundreds of characters strings. Unfortunatly, due to window.name features, whoever could simply use the same protocol to retrieve a key and to change its value. That is why next step is required.
sessionStorage Security PolicyLet's try to imagine we are in site a.com and we save a lot of data thanks to sessionStorage because we would like to make user experience as good as possible, remembering everything we need to remember, from massive written documents to whatever preference / option we would like to remember. sessionStorage is perfect for this purpose. Now, for some reason we have an external link in our web application, or the user simply surf another site in the same tab. We would like to remember his actions or preferences as soon as he comes back but attention, the website b.com could be a malicious one and it could try to read the window.name and changes key a with value b into key a with value c. It is extremely simple thanks to used protocol simplicity. That is why I had to implement something secure enough in order to avoid value modifications.
The Web Storage APIAs we can see, the W3 team did an excellent job here: there is everything we need to perform any kind of task.
lengthThis public ready only property, will tell us how many key/pair the sessionStorage contains. It is exactly like the length in a HTMLCollection, an Array, etc etc.
sessionStorage.length; // 0
sessionStorage.length; // 1key(i:int):stringThe public key method accept an integer (virtually unsigned) from 0 to sessionStorage.length - 1 This method returns the key used to store some value.
sessionStorage.key(0); // myKeygetItem(key:string):stringThis public method accepts any sort of string, used as key, and returns the associated string, as value, or null if that key has not been stored before. Please not that whatever stored value will be converted into a string, so the check 'if(getItem("key") === null)' is never ambiguous.
sessionStorage.getItem("test"); // null
sessionStorage.getItem("test"); // yosetItem(key:string, data:string):voidThis public method stores data via specified key. Please note that if key was already stored, it will overwrite it. Another thing to consider is that if we store a key, and via sessionStorage.key(0) we obtain that key, then we store another key/data and finally we store again the first key, sessionStorage.key(0) will return the second key/data stored, and not the first one.
removeItem(key:string):voidThis public method simply removes a key and related data from the storage.
sessionStorage.getItem("test"); // yo
sessionStorage.getItem("test"); // nullclear(void):voidThis public method remove everything from the sessionStorage object.
Compatibility & RequirementsAs I said before, this script should be compatible with every A-grade browser, included iPhone or Android, but please feel free to file a bug if you encountered problems with this implementation. As unique requirement, and only for not compatible browsers, cookies should be enabled in orther to save in a "secure way" the 128 characters randomly generated key and used for the entire session. Finally, if you have some comment or question, please do not hesitate to write a comment in the official announcement post in WebReflection.
P.S. this project will be part of the vice-versa as well. this dedicated space is to avoid to force my vice-versa library inclusion
These details are provided for information only. No information here is legal advice and should not be used as such.