O'Reilly logo

JavaScript Cookbook by Shelley Powers

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

20.4. Using sessionStorage for Client-Side Storage

Problem

You want to easily store session information without running into the size and cross-page contamination problems associated with cookies, and prevent loss of information if the browser is refreshed.

Solution

Use the new DOM Storage sessionStorage functionality:

sessionStorage.setItem("name", "Shelley");
sessionStorage.city="St. Louis";
...
var name = sessionStorage,getItem("name");
var city = sessionStorage.city;
...
sessionStorage.removeItem("name");
sessionStorage.clear();

Discussion

One of the constraints with cookies is they are domain/subdomain-specific, not page-specific. Most of the time, this isn’t a problem. However, there are times when such domain specificity isn’t sufficient.

For instance, a person has two browser tabs open to the same shopping site and adds a few items to the shopping cart in one tab. In the tab, the shopper clicks a button to add an item because of the admonishment to add the item to the cart in order to see the price. The shopper decides against the item and closes the tab page, thinking that action is enough to ensure the item isn’t in the cart. The shopper then clicks the check-out option in the other opened tag, assuming that the only items currently in the cart are the ones that were added in that browser page.

If the users aren’t paying attention, they may not notice that the cookie-based shopping cart has been updated from both pages, and they’ll end up buying something they didn’t want.

While it is true that many web users are savvy enough to not make this mistake, there are many who aren’t; they assume that persistence is browser-page-specific, not necessarily domain-specific. With sessionStorage (to paraphrase the famous quote about Las Vegas), what happens in the page, stays in the page.

As an example of the differences between the cookies and the new storage option, Example 20-4 stores information from a form in both a cookie and sessionStorage. Clicking the button to get the data gets whatever is stored for the key in both, and displays it in the page: the sessionStorage data in the first block, the cookie data in the second. The remove button erases whatever exists in both.

Example 20-4. Comparing sessionStorage and cookies

<!DOCTYPE html>
<html dir="ltr" lang="en-US">
<head>
<title>Comparing Cookies and sessionStorage</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
<style>
div
{
  background-color: #ffff00;
  margin: 5px;
  width: 100px;
  padding: 1px;
}
</style>
<script>
   window.onload=function() {

      document.getElementById("set").onclick=setData;
      document.getElementById("get").onclick=getData;
      document.getElementById("erase").onclick=removeData;
   }

   // set data for both session and cookie
   function setData() {
     var key = document.getElementById("key").value;
     var value = document.getElementById("value").value;

     // set sessionStorage
     var current = sessionStorage.getItem(key);
     if (current) {
       current+=value;
     } else {
       current=value;
     }
     sessionStorage.setItem(key,current);

     // set cookie
     current = getCookie(key);
     if (current) {
        current+=value;
     } else {
       current=value;
     }
     setCookie(key,current);
   }

   function getData() {
     try {
        var key = document.getElementById("key").value;

        // sessionStorage
        var value = sessionStorage.getItem(key);
        if (!value) value ="";
           document.getElementById("sessionstr").innerHTML="<p>" +
value + "</p>";

        // cookie
        value = getCookie(key);
        if (!value) value="";
           document.getElementById("cookiestr").innerHTML="<p>" +
value + "</p>";

     } catch(e) {
       alert(e);
     }
   }

   function removeData() {
     var key = document.getElementById("key").value;

     // sessionStorage
     sessionStorage.removeItem(key);

     // cookie
     eraseCookie(key);
   }
  // set session cookie
   function setCookie(cookie,value) {

      var tmp=cookie + "=" + encodeURI(value) + ";path=/";
      document.cookie=tmp;
   }

   // each cookie separated by semicolon;
   function getCookie(key) {

      var cookie = document.cookie;
      var first = cookie.indexOf(key+"=");

      // cookie exists
      if (first >= 0) {
         var str = cookie.substring(first,cookie.length);
         var last = str.indexOf(";");

         // if last cookie
         if (last < 0) last = str.length;

         // get cookie value
         str = str.substring(0,last).split("=");
         return decodeURI(str[1]);
       } else {
         return null;
       }
   }

   // set cookie date to the past to erase
   function eraseCookie (key) {
      var cookieDate = new Date();
      cookieDate.setDate(cookieDate.getDate() - 10);
      var tmp=key +
"= ; expires="+cookieDate.toGMTString()+"; path=/";
      document.cookie=tmp;
   }
</script>
</head>
<body>
   <form>
      <label for="key"> Enter key:</label>
<input type="text" id="key" /> <br /> <br />
      <label for="value">Enter value:</label>
 <input type="text" id="value" /><br /><br />
   </form>
   <button id="set">Set data</button>
   <button id="get">Get data</button>
   <button id="erase">Erase data</button>
   <div id="sessionstr"><p></p></div>
   <div id="cookiestr"><p></p></div>
</body>

Load the example page (it’s in the book examples) in Firefox 3.5 and up. Add one or more items to the same key value, and then click the button labeled “Get data”, as shown in Figure 20-2.

Now, open the same page in a new tab window, and click the “Get data” button. The activity results in a page like that shown in Figure 20-3.

In the new tab window, the cookie value persists because the cookie is session-specific, which means it lasts until you close the browser. The cookie lives beyond the first tab window, but the sessionStorage, which is specific to the tab window, does not.

Now, in the new tab window, add a couple more items to the key value, and click “Get data” again, as shown in Figure 20-4.

Showing current value for “apple” in sessionStorage and Cookie

Figure 20-2. Showing current value for “apple” in sessionStorage and Cookie

Again, showing current value for “apple” in sessionStorage and Cookie, but in a new tab window

Figure 20-3. Again, showing current value for “apple” in sessionStorage and Cookie, but in a new tab window

Return to the original tab window, and click “Get data”. As you can see in Figure 20-5, the items added in the second tab are showing with the cookie, but not the sessionStorage item.

Adding more values to “apple” in new tab window

Figure 20-4. Adding more values to “apple” in new tab window

Returning to the original tab window and clicking “Get data” with “apple”

Figure 20-5. Returning to the original tab window and clicking “Get data” with “apple”

Lastly, in the original tab window, click the “Erase data” button. Figure 20-6 shows the results of clicking “Get data” on the original window, while Figure 20-7 shows the results when clicking “Get data” in the second tab window. Again, note the disparities between the cookie and sessionStorage.

After clicking the “Erase data” button in the original tab window, and then clicking “Get data”

Figure 20-6. After clicking the “Erase data” button in the original tab window, and then clicking “Get data”

Clicking “Get data” in the second window, after erasing data in first

Figure 20-7. Clicking “Get data” in the second window, after erasing data in first

The reason for all of these images is to demonstrate the significant differences between sessionStorage and cookies, aside from how they’re set and accessed in JavaScript. Hopefully, the images and the example also demonstrate the potential hazards involved when using sessionStorage, especially in circumstances where cookies have normally been used.

If your website or application users are familiar with the cookie persistence across tabbed windows, sessionStorage can be an unpleasant surprise. Along with the different behavior, there’s also the fact that browser menu options to delete cookies probably won’t have an impact on sessionStorage, which could also be an unwelcome surprise for your users. Use sessionStorage with caution.

The sessionStorage object is currently supported in Firefox 3.5 and up, Safari 4.x and up, and IE 8. There are some implementation differences for sessionStorage, but the example shown in this recipe is consistently implemented across all environments.

One last note on sessionStorage, as it relates to its implementation. Both sessionStorage and localStorage, covered in the next recipe, are part of the new DOM Storage specification, currently under development by the W3C. Both are window object properties, which means they can be accessed globally. Both are implementations of the Storage object, and changes to the prototype for Storage result in changes to both the sessionStorage and localStorage objects:

Storage.prototype.someMethod = function (param) { ...};
...
localStorage.someMethod(param);
...
sessionStorage.someMethod(param);

Aside from the differences, covered in this recipe and the next, another major difference is that the Storage objects don’t make a round trip to the server—they’re purely client-side storage techniques.

See Also

For more information on the Storage object, sessionStorage, localStorage, or the Storage DOM, consult the specification. See Recipe 20.5 for a different look at how sessionStorage and localStorage can be set and retrieved, and other supported properties on both.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required