Browser Local Storage Solutions

Browser local storage solutions can be divided into three aspects, namely Cookie, Web Storage, and IndexedDB.

Because the HTTP protocol is stateless, once the data exchange is completed, the connection will be closed, and reconnecting is required for further data exchange, which means that the server cannot track the session from the connection. If both A and B purchase an item at the same time, without session tracking, the server cannot determine who actually bought the item. To enable session tracking, the server issues a pass to each client, and each visit requires carrying the pass, allowing the server to distinguish the user's identity.
Cookie is actually a small piece of text information that the server sends to the browser as a pass, and the browser stores the pass and automatically carries the pass information for each request from the same source (CSRF cross-site request forgery is based on this strategy), allowing the server to determine the user's identity.
Cookie is usually used to store some general data, such as user's login status, preferences, and not recommended for storing business data. Although with the advancement of technology, the storage mechanism provided by HTML5 has gradually replaced Cookie, some older browsers are still incompatible with the Web storage mechanism. Therefore, in some cases, Cookie may still be needed to store some business information to handle compatibility requirements.

Advantages

  • Cookie has very good compatibility and is compatible with all mainstream browsers on the market.

Disadvantages

  • Small storage capacity, although the storage capacity varies in different browsers, it is basically around 4KB.
  • Performance impact, because Cookie will be sent by the browser as a request header, so when there is excessive information stored in Cookie, it will affect the efficiency of resource acquisition for a specific domain and increase the workload of document transmission.
  • Security issues, any data stored in Cookie can be accessed, so sensitive information should not be stored in Cookie. In addition, important Cookie also needs to use HTTP ONLY to prevent malicious JS read and write.
  • Due to the abuse of third-party Cookie, some users may disable Cookie while browsing the web, so we have to test whether the user supports Cookie.

Operation

A complete Unicode-supported Cookie reader/writer.

/*\
|*|
|*|  :: cookies.js ::
|*|
|*|  A complete cookies reader/writer framework with full unicode support.
|*|
|*|  https://developer.mozilla.org/en-US/docs/DOM/document.cookie
|*|
|*|  This framework is released under the GNU Public License, version 3 or later.
|*|  http://www.gnu.org/licenses/gpl-3.0-standalone.html
|*|
|*|  Syntaxes:
|*|
|*|  * docCookies.setItem(name, value[, end[, path[, domain[, secure]]]])
|*|  * docCookies.getItem(name)
|*|  * docCookies.removeItem(name[, path], domain)
|*|  * docCookies.hasItem(name)
|*|  * docCookies.keys()
|*|
\*/


```javascript
var docCookies = {
  getItem: function (sKey) {
    return decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(sKey).replace(/[-.+*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) || null;
  },
  setItem: function (sKey, sValue, vEnd, sPath, sDomain, bSecure) {
    if (!sKey || /^(?:expires|max\-age|path|domain|secure)$/i.test(sKey)) { return false; }
    var sExpires = "";
    if (vEnd) {
      switch (vEnd.constructor) {
        case Number:
          sExpires = vEnd === Infinity ? "; expires=Fri, 31 Dec 9999 23:59:59 GMT" : "; max-age=" + vEnd;
          break;
        case String:
          sExpires = "; expires=" + vEnd;
          break;
        case Date:
          sExpires = "; expires=" + vEnd.toUTCString();
          break;
      }
    }
    document.cookie = encodeURIComponent(sKey) + "=" + encodeURIComponent(sValue) + sExpires + (sDomain ? "; domain=" + sDomain : "") + (sPath ? "; path=" + sPath : "") + (bSecure ? "; secure" : "");
    return true;
  },
  removeItem: function (sKey, sPath, sDomain) {
    if (!sKey || !this.hasItem(sKey)) { return false; }
    document.cookie = encodeURIComponent(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT" + ( sDomain ? "; domain=" + sDomain : "") + ( sPath ? "; path=" + sPath : "");
    return true;
  },
  hasItem: function (sKey) {
    return (new RegExp("(?:^|;\\s*)" + encodeURIComponent(sKey).replace(/[-.+*]/g, "\\$&") + "\\s*\\=")).test(document.cookie);
  },
  keys: /* optional method: you can safely remove it! */ function () {
    var aKeys = document.cookie.replace(/((?:^|\s*;)[^\=]+)(?=;|$)|^\s*|\s*(?:\=[^;]*)?(?:\1|$)/g, "").split(/\s*(?:\=[^;]*)?;\s*/);
    for (var nIdx = 0; nIdx < aKeys.length; nIdx++) { aKeys[nIdx] = decodeURIComponent(aKeys[nIdx]); }
    return aKeys;
  }
};

Web Storage

The Web storage mechanism was initially defined as part of HTML5 in the form of an API, but it was later separated and became an independent standard due to its uniqueness and various other reasons. The Web storage standard API includes the localStorage object and the sessionStorage object. Its emergence is mainly due to the need for a way to store session data outside of cookies, as well as a mechanism to store a large amount of data that can exist across sessions. In fact, the original Web storage specification included the definition of two objects: sessionStorage and globalStorage, both of which exist in browsers that support these objects in the form of properties of the Window object.

localStorage

The localStorage object, as a solution for persistently storing client-side data, replaced the previously mentioned globalStorage in the revised HTML5 specification. Compared to cookies, localStorage provides a simple and clear API for operation, is more secure, and can store a larger amount of data. For these reasons, localStorage is considered as an alternative to cookies, but caution should still be taken not to store sensitive information in localStorage.
The data stored through localStorage is permanent, unless we use removeItem to delete it or the user deletes it by configuring the browser. The data will remain on the user's computer indefinitely. The scope of localStorage is limited to the document origin level, meaning that only documents from the same origin can share it. Documents from the same origin can share localStorage data, read each other's data, and implement communication between same-origin windows through the onstorage event, although the scope of localStorage is also subject to browser restrictions.

sessionStorage

sessionStorage is another major object of the Web storage mechanism. The sessionStorage property allows us to access a session Storage object, which is similar to localStorage but differs in that the data stored in localStorage does not have an expiration time set, while Session Storage only stores data for the current session page, and the data is only cleared when the user closes the current session page or browser. Additionally, pages derived from a session can also access the previously set data, even if the newly derived page is not from the same origin as the source page.

Usage

// Store data
localStorage.setItem("key", "value");
sessionStorage.setItem("key", "value");
/**
 * Since storing data calls the toString() method,
 * object types will be stored as the string [object Object]
 * so when storing, use JSON.stringify() to convert to a string
 * when retrieving, use JSON.parse() to convert the string back to an object
 */

// Read data
localStorage.getItem("key");
sessionStorage.getItem("key");

// Delete data
localStorage.removeItem("key");
sessionStorage.removeItem("key");

// Clear data
localStorage.clear();
sessionStorage.clear();

IndexedDB

Although the Web storage mechanism is very convenient for storing small amounts of data, it is not quite suitable for developers' needs in storing larger amounts of structured data. IndexedDB was created to address this need. It is a local storage provided by HTML5 for storing large data structures in a web browser and provides indexing capabilities for high-performance searching. It is generally used to save a large amount of user data and for scenarios that require searching between data. When the network is disconnected, users can perform some offline operations.

Usage

An example of using IndexedDB to facilitate communication between multiple same-origin tabs.

// Page A
var db = null;
var request = indexedDB.open("message");
request.onsuccess = (e) => db = e.target.result;
request.onupgradeneeded = function(event) {
    db = event.target.result;
    if (!db.objectStoreNames.contains('message')) {
        db.createObjectStore('message', { keyPath: 'key' });
    }
};

function setData(data){
    var transaction = db.transaction(['message'], 'readwrite');
    var store = transaction.objectStore(['message']);
    var requestData = store.put({ key: "msg", info: data});
    requestData.onsuccess = function(e) { 
        console.log(e.target.result);
    };
};

setTimeout(() => setData(1),1000);
// Page B
var db = null;
var request = indexedDB.open("message");
request.onsuccess = (e) => db = e.target.result;
function readMsg(){
    var transaction = db.transaction(['message']);
    var objectStore = transaction.objectStore('message');
    var requestResult = objectStore.get('msg');

    requestResult.onsuccess = function(event) {
        console.log(requestResult.result.info);
   };
}

setTimeout(readMsg, 3000);

Daily question

https://github.com/WindrunnerMax/EveryDay

Reference

https://zhuanlan.zhihu.com/p/146050407 https://juejin.cn/post/6844904193694646280 https://developer.mozilla.org/zh-CN/docs/Web/API/Document/cookie https://developer.mozilla.org/zh-CN/docs/Web/API/Window/localStorage https://www.cnblogs.com/fengyuqing/archive/2013/05/31/localStorage.html https://developer.mozilla.org/zh-CN/docs/Web/API/IndexedDB_API/Using_IndexedDB