The original intention of this series of articles is to “let each front-end engineer master the high frequency knowledge, for the work of power”. This is the front end of the number 24 cut, I hope friends pay attention to the public number “kite”, armed with knowledge of their minds.

Open the Application section of the browser developer tool, and you can see that the browser supports five storage modes: localStorage, sessionStorage, IndexedDB, WebSQL, and Cookie. In November 2011, W3C officially announced that it would no longer maintain the Web SQL Database specification. Therefore, this paper mainly discusses the other three Storage methods: Cookie, Storage, and IndexedDB.

24.1 the Cookie

24.1.1 definition

A Cookie is a simple text file stored in a browser, which is associated with a specific Web document and holds information about the Web document when the browser accesses it, which is available for use when the browser accesses the Web document again. (HTTP is stateless protocol, that is, HTTP protocol itself does not save the communication state between request and response, in order to achieve the desired function of saving state, cookie technology is introduced)

24.1.2 of cookies

Before understanding the composition of Cookie, let’s first understand the whole request process of Cookie. This process is divided into two categories: one is the request in the state without Cookie information, and the other is the request in the state with Cookie.

It can be seen from the above flow chart that the Cookie is generated at the server. After querying the data, it is found that the Cookie is the information of the head field called set-cookie in the response packet sent from the server. If there is this head field in the response packet, the client is informed to save the Cookie. The composition of Cookie is related to the values that set-cookie can Set. At present, there are mainly the following categories:

  1. NAME=VALUE The NAME and VALUE of the Cookie, where NAME is the NAME that uniquely identifies the Cookie and is case insensitive. VALUE is a string VALUE stored in a Cookie that must be URL-encoded.

  2. Domain= Domain name Indicates the Domain to which the Cookie is valid. All requests to this Domain contain the Cookie. (If not specified, defaults to the domain name of the server that created the Cookie.)

  3. Path= Path The Cookie is sent to the server only if it is included in the request URL (default is the file directory of the document if not specified)

  4. Expires=DATE Indicates the expiration DATE of the Cookie. By default, all cookies are deleted after the browser session ends.

  5. After Secure is set, cookies are sent only for Secure HTTPS communication

  6. HttpOnly can only be read on the server. Cookies cannot be read through JavaScript

const express = require('express'); const app = express(); app.get('/', (req, res) => { res.cookie('myCookie', 'myCookie', { expires: new Date(Date.now() + 900000), secure: true, httpOnly: true }); Res.send (' Get request has been processed '); }) app.listen(8090, () => {console.log(' port 8090 started!! '); });Copy the code

To see the results, request http://127/.0.0.1:8090:

  1. Cookie result returned for the first time
  2. Cookie information carried with subsequent requests

24.1.3 Cookie characteristics

  1. Each Cookie does not exceed 4096 bytes;
  2. There is a limit to the number of cookies per domain, such as the latest version of IE and Edge: no more than 50; Firefox no more than 150; Opera has no more than 180; Safari and Chrome have no limits;
  3. If the number of cookies exceeds the upper limit for a single domain, the browser deletes the cookies previously set.
  4. If the number of cookies created exceeds the upper limit, the cookies will be silently deleted.
  5. The invalid time can be set. If it is not set, the Cookie will be deleted at the end of the session.
  6. Each request carries cookies. Too many cookies may cause performance problems.
  7. The policy is restricted by the same origin policy

24.1.4 Operation of Cookie

Cookies can still be read, written and deleted after they are stored in the browser. As JS does not support Cookie operations very friendly, some simple encapsulation is needed.

Class CookieUtil {static get(name) {const cookies = document.cookie; const cookiesArr = cookies.split('; '); for (let index = 0; index < cookiesArr.length; index++) { const presentCookieArr = cookiesArr[index].split('='); if (presentCookieArr[0] === name) { return presentCookieArr[1]; } } return null; } static set(name, value, Expires, path, domain, secure) {let cookieText = '${name}=${value}'; if (expires instanceof Date) { cookieText += `; expire=${expires.toGMTString()}`; } if (path) { cookieText += `; path=${path}`; } if (domain) { cookieText += `; domain=${domain}`; } if (secure) { cookieText += `; secure`; } document.cookie = cookieText; } // delete the corresponding Cookie static deleteCookie(name) {cookieutil. set(name, '', new Date(0)); }}Copy the code

24.2 Web Storage

The purpose of Web Storage is to solve the problem of using cookies through the client to store data that does not need to be frequently sent back to the server. It provides a way to store session data other than cookies and a mechanism for storing a large amount of data across sessions. It mainly has two objects: LocalStorage and sessionStorage, localStorage is the permanent storage mechanism, sessionStorage is the cross-session storage mechanism.

24.2.1 sessionStorage

SessionStorage is a cross-session storage mechanism with the following features:

  1. SessionStorage object values store session data, whose life cycle is stored until the browser closes. (The data is not affected when the page is refreshed during this process)
  2. Browsers use synchronous blocking when implementing storage writes, and the data is immediately committed to storage.
  3. Independently open the same window the same page ora Tab, sessionStorage is also not the same.
  4. The storage space is limited to 5M for each source.
SetItem ('sessionName1', 'value1'); sessionStorage.setitem ('sessionName1', 'value1'); / / use attributes to store data sessionStorage. SessionName2 = 'value2'; // Const sessionValue1 = sessionStorage.getitem ('sessionName1'); Console. log('sessionValue1: ', sessionValue1); / / use the property data const sessionValue2 = sessionStorage. SessionName2; Console. log('sessionValue2: ', sessionValue2); SessionStarage for (let index = 0; index < sessionStorage.length; Index ++) {// Use key() to get the name of the specified index const key = sessionstorage.key (index); const value = sessionStorage.getItem(key); Console. log(' loop through result: ', key, value); } / / use delete sessionStorage. RemoveItem (' sessionName1 '); / / use the delete delete delete value sessionStorage. SessionName2; Sessionstorage.clear (); // Use the clear() method to clear sessionStorage.clear();Copy the code

24.2.2 localStorage

LocalStorage is a permanent storage mechanism that has the following features:

  1. The life cycle is permanent and lasts forever unless it is removed.
  2. The storage space is limited to 5M for each source.
  3. The policy is restricted by the same origin policy.
  4. The browser uses synchronous storage.
Localstorage.setitem ('localName1', 'value1'); Localstorage. localName2 = 'value2'; Const localValue1 = localstorage.getitem ('localName1'); Console. log('localValue1: ', localValue1); Const localValue2 = localstorage.localname2; Console. log('localValue2: ', localValue2); // loop over localStarage for (let index = 0; index < localStorage.length; Index++) {// use key() to get the name of the specified index const key = localstorage.key (index); const value = localStorage.getItem(key); Console. log(' loop through result: ', key, value); } // Delete localstorage.removeItem ('localName1'); // Use delete to delete the value delete localstorage. localName2; // Use the clear() method to clear localStorage localstorage.clear ();Copy the code

24.3 with IndexedDB

24.3.1 Entire structure of IndexedDB

For the entire IndexedDB as shown in the figure above:

  1. A domain name can contain multiple databases.
  2. Having multiple object repositories in a database is similar to having multiple tables in a Mysql library.
  3. Each object repository contains multiple data records.

24.3.2 Main features

IndexedDB is a scheme for storing structured data in a browser. Designed almost entirely asynchronously, IndexedDB has the following features:

  1. Key-value pairs are stored in object repositories, where data is stored as “key-value pairs,” with each data record having a unique primary key.

  2. Asynchronous IndexedDB operations do not lock the browser, and users can still perform other operations.

  3. Support transaction as long as there is a failure in some steps, the whole transaction is cancelled, the database is rolled back to the state before the transaction occurred, there is no case of rewriting only part of the data.

  4. Restricted by the same Origin policy, users can access only the databases under their own domain names, but cannot access databases across domains.

  5. Large storage space each source has a storage space limit, which is browser-dependent. For example, Firefox limits each source to 50MB and Chrome to 5MB.

  6. Support for binary storage can store not only strings but also binary data (ArrayBuffers and BLOBs)

24.3.3 Database Operations

IndexedDB, like many other databases, has a number of operations, which we’ll take a look at in action.

24.3.3.1 Initializing the Database

The first step is to initialize the database, pass in the created database name and version, and get the corresponding database operation instance.

class IndexedDBOperation { constructor(databaseName, version) { this.atabaseName = databaseName; this.version = version; this.request = null; this.db = null; } // Database initialization init() {this.request = window.indexeddb.open (this.databasename, this.version); return new Promise((resolve, reject) => { this.request.onsuccess = event => { this.db = event.target.result; Console. log(' database opened successfully '); resolve('success'); }; This.request. onerror = event => {console.log(' database open error '); reject('error'); }; this.request.onupgradeneeded = event =>{ this.db = event.target.result; Console. log(' database upgrade '); resolve('upgradeneeded'); }; }); }}Copy the code
24.3.3.2 Object warehouse Operations

The data is stored in the object warehouse, and once the database is created, the required data warehouse needs to be created

IndexedDBOperation {//...... CreateObjectStore (objectStoreName, options) {let objectStore = null; if (! this.db.objectStoreNames.contains(objectStoreName)) { objectStore = this.db.createObjectStore(objectStoreName, options); } return objectStore; }}Copy the code
24.3.3.3 Data operations

CURD is absolutely essential for both relational and non-relational databases, we are CURD engineers!!

IndexedDBOperation {//...... // add(objectStore, content) {objectstore.add (content); } get(objectStore, id) {const request = objectstore.get (id); return new Promise((resolve, reject) => { request.onsuccess = resolve; request.onerror = reject; }); } update(objectStore, content) {const request = objectstore.put (content); Request. Onsuccess = event => {console.log(' update succeeded '); }; Request. onerror = event => {console.log(' update failed '); }; } // remove(objectStore, deleteId) {const request = objectStore.delete(deleteId); Request. Onsuccess = event => {console.log(' deleted successfully '); }; Request. onerror = event => {console.log(' delete failed '); }; }}Copy the code
24.3.3.4 Traversal content

When it comes to IndexedDB databases, it is important to mention their cursor operations.

IndexedDBOperation {//...... PrintAllDataByCursor (objectStore) {const cursorRequest = objectStore.opencursor (); cursorRequest.onsuccess = event => { const cursor = event.target.result; If (cursor) {console.log(' use cursor print, id ${cursor.key}, value ${cursor.value} '); // Move to the next record cursor.continue(); }}; }}Copy the code
24.3.3.5 Calling code

Write a database class above, but still do not know how to call ah, the following uses a demo to describe its call.

const indexedDBOperation = new IndexedDBOperation('dbName1', 1); indexedDBOperation .init() .then(type => { const objectStoreName = 'testObjectStore'; if (type === 'upgradeneeded') { indexedDBOperation.createObjectStore(objectStoreName, { keyPath: 'id' }); } const transaction = indexedDBOperation.db.transaction([objectStoreName], 'readwrite'); const objectStore = transaction.objectStore(objectStoreName); indexedDBOperation .get(objectStore, (1). Then the event = > {the if (event. The target. The result) {indexedDBOperation. Update (objectStore, {id: 1, name: 'hold + kite kite,'}); Console. log(' already exists in database ', event.target.result, ', then update '); } else {indexeddbOperation. add(objectStore, {id: 1, name: 'id'}); Console. log(' not in database, add '); } }) .catch(console.log); indexedDBOperation.printAllDataByCursor(objectStore); Transaction. Onsuccess = event => {console.log(' transaction succeeded '); }; Transaction. Onerror = event => {console.log(' transaction failed '); }; Transaction. Oncomplete = event => {console.log(' entire transaction completed successfully '); } }) .catch(console.log);Copy the code

1. If you think this article is good, share and like it so that more people can see it

2. Pay attention to the public number of kite, and the number of the Lord together to kill the front hundred