Safari Reference Library Apple Developer
Search

Key-Value Storage

Beginning in Safari 4.0, Safari supports the HTML 5 client-side storage specification. One portion of that specification is key-value storage. The purposes of key-value storage are twofold:

To support those goals, the HTML 5 specification provides two key-value storage objects: sessionStorage and localStorage.

The localStorage and sessionStorage JavaScript objects are functionally identical except in their persistence and scope rules:

Except for these differences, the localStorage and sessionStorage objects behave identically.

Like cookies, these objects provide different sets of data to pages served by different domains. Unlike cookies, the data is not transmitted back to the server during normal browsing. If you need to send the stored data back to the server, you must do so explicitly using JavaScript and an XMLHttpRequest object.

Note: The underlying storage pool is not shared between the localStorage and sessionStorage objects. Thus, it is not possible to obtain a key stored with localStorage by reading it from sessionStorage or vice versa. To avoid confusion, you should generally not store the same key in both storage objects.

Using Session and Local Storage

This section describes how to store, retrieve, and delete key-value pairs using the session storage or local storage objects. Because session storage and local storage objects behave similarly, the examples in this section all use session storage for consistency.

You can change these examples to use local storage by substituting the localStorage object in place of the sessionStorage object wherever it appears in the code.

Storing and Retrieving Values

To store a value in key-value storage, use the setItem method. This method takes two parameters: a name and a value.

Consider a website that holds regular contests with various prizes. You might elect to store the user’s shirt size so that every time the user enters a contest that requests a shirt size, your JavaScript code can populate the shirt size field automatically with the last value chosen. You can store the value with the following line of code:

// Store the value of the variable "myShirtSize" into the
// session storage field named "shirt_size".
sessionStorage.setItem("shirt_size", myShirtSize);

If you want to store the value in local storage, simply use the localStorage object instead. For example:

localStorage.setItem("shirt_size", myShirtSize);

Storing data can throw an exception if you exceed a browser-specific quota. If the data you are storing is important, you should check for this exception and handle it. For example:

try {
    sessionStorage.setItem("shirt_size", myShirtSize);
} catch (e) {
    if (e == QUOTA_EXCEEDED_ERR) {
        alert('Quota exceeded.');
    }
}

In your onload method, you might then retrieve that value and populate the form field as appropriate with code like this:

var myShirtSize = sessionStorage.getItem("shirt_size");
 
// do something with the value here.
document.getElementById('shirt_size').value = myShirtSize;

If no key-value pair with the specified name exists, myShirtSize is set to null.

If your key name is a valid JavaScript token (no spaces, punctuation other than underscore, and so on), you can also retrieve the value like this:

var myShirtSize = sessionStorage.shirt_size;

You can find out the total number of keys (for your domain) in session storage by examining the value stored in sessionStorage.length. For example:

alert('there are '+sessionStorage.length+' items in the session storage array.');

Finally, you can obtain a key based on a numeric index.

var value;
var index = 3;
try {
    value = sessionStorage(index);
} catch(e) {
    if (e == INDEX_SIZE_ERR) {
        alert('There are fewer than '+(index-1)+' keys in the session storage object.');
    }
}

This method throws an exception if the index is not within the range [0..n-1] where n is the number of keys in the storage object.

Deleting Values

There are two ways to delete values from key-value storage: individually or en masse. To delete a single value (continuing the shirt size example from the previous section), use the following line of code:

sessionStorage.removeItem("shirt_size");

To remove all key-value pairs for your domain, use the following line of code:

sessionStorage.clear();

Handling Storage Events

Like cookies, storage objects are a shared resource common to web content served from the same domain. All pages from the same domain share the same local storage object. Frames and inline frames also share the same session storage object because they descend from the same window.

Because this resource is shared, scripts running in multiple page contexts can potentially modify the data stored in a storage object that is actively being scrutinized or modified by a script running on a different page. If your scripts do not notice these changes, you may not get the results you expect.

To this end, storage objects generate an event of type storage whenever a script adds, deletes, or modifies a value in key-value storage so that your scripts can notice changes to local or session storage by other scripts and act on them.

Before you can receive storage events, you must first register for them by executing the following line of code:

window.addEventListener('storage', storage_handler, false);

Once you have registered an event handler, the specified function (in this case, storage_handler) is called whenever a script modifies either local or session storage. Here is a simple handler that shows an alert for each field in a storage event:

function storage_handler(evt)
{
    alert('The modified key was '+evt.key);
    alert('The original value was '+evt.oldValue);
    alert('The new value is '+evt.newValue);
    alert('The URL of the page that made the change was '+evt.url);
    alert('The window where the change was made was '+evt.source);
}

This example, while simple, shows the five event fields relevant to a storage event. The fields are as follows:

key

The key that was modified. If the session or local storage object is wiped with the clear method, the value of key is null.

oldValue

The previous value of the modified key. If the key is newly created, the value of oldValue is null. If the storage object is wiped with the clear method, the value is also null.

newValue

The current (new) value of the modified key. If the key is deleted with the clear method, the value of key is null. If the storage object is wiped with the clear method, the value is also null.

url

The URL of the page that added, modified, or deleted the key. The url field is only available if the page that made the change is in the same browsing context (a single tab in a single window). Otherwise, the url field value will be null.

source

The Window object containing the script that modified the key. The source field is only available if the page that made the change is in the same browsing context (a single tab in a single window). Otherwise, the source field value will be null.

A Complete Example

This HTML page demonstrates local and session storage. If you modify the values in either field, they are stored locally (both on modification and on page exit) and are retrieved when you reload the page. If you close the window and then load the page again, only the value stored in local storage is restored.

This example is also included in the attached Companion Files archive.

<html>
<head>
<script language="JavaScript" type="text/javascript"><!--
 
function restoreValues()
{
    if (typeof(sessionStorage) == 'undefined' || typeof(localStorage) == 'undefined') {
        alert('local and session storage not supported by this browser.');
    }
    document.getElementById('myfield1').value = sessionStorage.myfield1 ? sessionStorage.myfield1 : "";
    document.getElementById('myfield2').value = localStorage.getItem('myfield2') ? localStorage.getItem('myfield2') : "";
 
    // Save changes if the user leaves the page.
    window.onbeforeunload = function () {
        return saveChanges();
    };
 
}
 
function clearAll()
{
    sessionStorage.clear();
    localStorage.clear();
    restoreValues();
}
 
 
function setValue(value)
{
    if (value == 'myfield1') {
        sessionStorage.setItem(value, document.getElementById(value).value);
    } else {
        localStorage.setItem(value, document.getElementById(value).value);
    }
}
 
function saveChanges()
{
    setValue('myfield1');
    setValue('myfield2');
 
    return NULL;
}
 
function clearValue(value)
{
    if (value == 'myfield1') {
        sessionStorage.removeItem(value);
    } else {
        localStorage.removeItem(value);
    }
    document.getElementById(value).value = '';
}
 
--></script>
 
</head>
<body onload='restoreValues()'>
 
<p>Field 1 is stored in session storage, field 2 in local storage.  Both should be retrieved on a page reload, but field 1 should not be retrieved if you close the window and reopen it.</p>
 
<p>
<input id='myfield1' onchange='setValue("myfield1")'>Field 1</input><br />
<input id='myfield2' onchange='setValue("myfield2")'>Field 2</input>
</p>
 
<p>
<a href='#' onclick='clearValue("myfield1")'>clear value 1</a><br />
<a href='#' onclick='clearValue("myfield2")'>clear value 2</a><br />
<a href='#' onclick='clearAll()'>clear all</a><br />
</p>
 
</body>
</html>

Concurrency Considerations

Key-value storage is no more concurrency-safe than cookies. Most JavaScript code tends to perform work in response to user actions, which means there is little actual concurrency involved. However, if your code needs to do regularly read and write to session storage objects for other purposes, you must do a bit of extra work.




Last updated: 2010-01-20

Did this document help you? Yes It's good, but... Not helpful...