Cookie, localStorage, sessionStorage, indexedDB, etc.

Cookie

Cookies are some data that the server entrusts the browser to store, which gives the server “memory capacity” and will be carried and sent to the server when the browser sends a request to the server again.

How cookies work

Two fields are used: the response header field set-cookie and the request header field Cookie.

  • Response Message UsageSet-CookieField send”key=valueIn the form of”Cookie
  • Used in request messagesCookieSend multiple fieldsCookie

The attribute of the Cookie

Cookie lifetime: This can be set using the Expires and max-age attributes

  • ExpiresExpiration time, in terms of absolute points in time, can be understood as “due date” (deadline).
  • Max-AgeThe relative time is in seconds, and the browser uses the time at which the message was received plusMax-Age, the absolute time of failure can be obtained.
  • ExpiresMax-AgeIf both can be present, the browser will preferentially use themMax-AgeCalculate the expiration period.

Cookie scope: allows the browser to send only to a specific server and URI, to avoid theft by other sites.

  • DomainPathSpecifies theCookieBelongs to the domain name and path the browser is sendingCookieFrom beforeURIextracthostpathPart, contrastCookieProperties.
  • If the criteria are not met, it will not be sent in the request headerCookie.

Security of cookies: Try not to let anyone outside the server see them.

  • HttpOnly:CookieOnly HTTP can be used to transmit data. Other methods, such as JS, are prohibitedCookie, reduce XSS attacks;
  • SameSite:SameSiteCan be set to defend against XSRF (Cross-site request forgery) attacksSameSite=StrictIt can be strictly definedCookieCannot be sent across sites with jump links, whileSameSite=LaxIt’s a little bit looser, it’s allowedGET/HEADAnd other safe methods, but prohibitedPOSTCross-site send
  • Secure: means thisCookieOnly the HTTPS protocol can be used for encrypted transmission, and the plaintext HTTP protocol forbids sending.

The application of the Cookie

  • identification:CookieOne of the most basic uses is identification, saving user login information, and realizing session transactions
  • AD tracking: Advertiser sites (e.g., Google) that secretly label youCookieA little note, so you can go to other sites, other ads can be usedCookieRead your identity, do a behavioral analysis, and then push the AD to you.

The characteristics of the Cookie

  • Data life cycle: Generally generated by the server, you can set the expiration time
  • Data store size:CookieIs limited in size, generally4 KB
  • Communicates with the server: Each time an HTTP request in the same domain is sent, the HTTP request is sent inheaderIs carried under the current domain nameCookie, affecting the performance of the request

Cookie Usage Example

// Read all cookies under the website, get the result is a semicolon '; 'as a string to be split
let allCookies = document.cookie;

// Add a new cookie to the existing cookie
document.cookie ="name=vincent";

You can also add optional option key-value pairs, such as Domain, path, expires
document.cookie="name=vincent; domain=.test.com"

// To delete a cookie, set expires to 0
document.cookie="name=vincent; domain=.test.com; expires=0");
Copy the code

localStorage

This is persistent storage, which means that data will never expire unless it is manually cleaned up. It uses key-value pair to store data and saves the data to the corresponding database file according to the domain name. It can hold much more data than a Cookie.

The characteristics of localStorage

  • Data life cycle: It persists unless it is cleaned up
  • Data store size: 5M
  • Communicate with the server: Does not communicate with the server

LocalStorage Example

// setItem() sets the properties
localStorage.setItem('name'.'vincent');

// getItem() retrieves data
let name = localStorage.getItem('name');

// removeItem() removes an attribute
localStorage.removeItem('name');

// clear() removes all data items
localStorage.clear();
Copy the code

Emulation implements a localStorage

class myLocalStorage {
  constructor() {
    this.store = {};
  }
  setItem(key, val) {
    this.store[key] = val;
  }
  getItem(key) {
    return this.store[key] || null;
  }
  removeItem(key) {
    delete this.store[key]
  }
  clear() {
    this.store = {}; }}Copy the code

Implement the expiration time function

(function () {
  let getItem = localStorage.getItem.bind(localStorage)
  let setItem = localStorage.setItem.bind(localStorage)
  let removeItem = localStorage.removeItem.bind(localStorage)
  localStorage.getItem = function (keyName) {
    let expires = getItem(keyName + '_expires')
    if (expires && new Date(a) >new Date(Number(expires))) {
      removeItem(keyName)
      removeItem(keyName + '_expires')}return getItem(keyName)
  }
  localStorage.setItem = function (keyName, keyValue, expires) {
    if (typeofexpires ! = ='undefined') {
      let expiresDate = new Date(expires).valueOf()
      setItem(keyName + '_expires', expiresDate)
    }
    return setItem(keyName, keyValue)
  }
})()
Copy the code

sessionStorage

SessionStorage is a session-level cache that is cleared when the browser is closed.

Note that the scope of sessionStorage is window level, that is, sessionStorage data stored between different Windows cannot be shared.

The characteristics of the sessionStorage

  • Data life cycle: The data remains after the page is refreshed, but is erased when the browser TAB is closed
  • Data store size: 5M
  • Communicate with the server: Does not communicate with the server

SessionStorage Example

SessionStorage and localStorage have the same API interface:

// setItem() sets the properties
sessionStorage.setItem('name'.'vincent');

// getItem() retrieves data
let name = sessionStorage.getItem('name');

// removeItem() removes an attribute
sessionStorage.removeItem('name');

// clear() removes all data items
sessionStorage.clear();
Copy the code

indexedDB

IndexedDB is a NoSQL database, a transactional browser database used by clients to store large amounts of structured data, including files and binary large objects.

The characteristics of with indexedDB

  • Data life cycle: It persists unless it is cleaned up
  • Data store size: Unlimited
  • Communicate with the server: Does not communicate with the server

IndexedDB example

Create or open a database using the indexeddb.open () method
var request = window.indexedDB.open(dbName, version); // Database name version number
// The error event indicates that the database fails to be opened
request.onerror = function (event) {
  console.log('Failed to create or open database');
};
// Success indicates that the database is opened successfully
var db;
request.onsuccess = function (event) {
  db = request.result;
  console.log('Database created or opened successfully');
};
Copy the code

Here is some code for indexDB that I used for a previous project:

Database name (myDB) 2 version (1.0) 3 Description (Test DB) 4 Database size (2*1024*1024) */
var sqliteDB = function (db_name, size) {
  var _db = openDatabase(db_name, '1.0.0'.' ', size); // Build or open the database
  var currSql = null;
  return {
    /** * Execute SQL, return the number of affected items */
    execute: function (sql, param, callback) {
      currSql = sql;
      // Parameter processing
      if(! param) { param = []; }else if (typeof param == 'function') {
        callback = param;
        param = [];
      }

      this.query(sql, param, function (result) {
        if (typeof callback == 'function') { callback(result.rowsAffected); }}); },/** * select * from 'SQL'; /** * from 'SQL'; Void query(string[, function]) * void Query (string[, array[, function]]) */
    query: function (sql, param, callback) {
      currSql = sql;
      // Parameter processing
      if(! param) { param = []; }else if (typeof param == 'function') {
        callback = param;
        param = [];
      }

      var self = this;
      // There is only one argument
      _db.transaction(function (tx) {
        // 4 arguments: SQL, replace the array of question marks in SQL, success callback, error callback
        tx.executeSql(sql, param, function (tx, result) {
          if (typeof callback == 'function') {
            callback(result);
          }
        }, self.onfail);
      }, self.onTransactionFail);
    },

    executeSql: function (sql, param, callback) {
      currSql = sql;
      // _db.transaction(fn, success, error);
      // Parameter processing
      if(! param) { param = []; }else if (typeof param == 'function') {
        callback = param;
        param = [];
      }

      var self = this;
      // There is only one argument
      _db.transaction(function (tx) {
        // 4 arguments: SQL, replace the array of question marks in SQL, success callback, error callback
        tx.executeSql(sql, param, function (tx, result) {
          if (typeof callback == 'function') {
            callback(result);
          }
        }, self.onfail);
      }, self.onTransactionFail);
      // console.log(sql);
    },
    Last id * void insert(string, object[, function]) */
    insert: function (table, data, callback) {
      if (typeofdata ! ='object' && typeof callback == 'function') {
        callback(0);
      }
      var k = [];
      var v = [];
      var param = [];
      for (var i in data) {
        k.push(i);
        v.push('? ');
        param.push(data[i]);
      }
      var sql = "INSERT INTO " + table + "(" + k.join(', ') + ") VALUES(" + v.join(', ') + ")";
      currSql = sql;
      this.query(sql, param, function (result) {
        if (typeof callback == 'function') { callback(result.insertId); }}); },/** * modify, * void update(string, object[, string[, function]]) * void update(string, object[, string[, array[, function]]]) */
    update: function (table, data, where, param, callback) {
      // Parameter processing
      if(! param) { param = []; }else if (typeof param == 'function') {
        callback = param;
        param = [];
      }

      var set_info = this.mkWhere(data);
      for (var i = set_info.param.length - 1; i >= 0; i--) {
        param.unshift(set_info.param[i]);
      }
      var sql = "UPDATE " + table + " SET " + set_info.sql;
      if (where) {
        sql += " WHERE " + where;
      }
      currSql = sql;
      this.query(sql, param, function (result) {
        if (typeof callback == 'function') { callback(result.rowsAffected); }}); },Void toDelete(string, string[, function]]) * void toDelete(string, string[, array[, function]]) */
    del: function (table, where, param, callback) {
      // Parameter processing
      if(! param) { param = []; }else if (typeof param == 'function') {
        callback = param;
        param = [];
      }

      var sql = "DELETE FROM " + table + " WHERE " + where;
      currSql = sql;
      this.query(sql, param, function (result) {
        if (typeof callback == 'function') { callback(result.rowsAffected); }}); },/*** * transaction */
    transaction: function (fn, success, error) {
      var hookError = function (tx, e) {
        console.log(tx.message);
        if (error) error(tx, e);
      };
      _db.transaction(fn, hookError, success);
      //_db.transaction(fn, error,success);
    },
    Void fetch_all(string[, function]) * void fetch_all(string[, param[, function]]) */
    fetchAll: function (sql, param, callback) {
      currSql = sql;
      // Parameter processing
      if(! param) { param = []; }else if (typeof param == 'function') {
        callback = param;
        param = [];
      }

      this.query(sql, param, function (result) {
        if (typeof callback == 'function') {
          var out = [];
          if (result.rows.length) {
            for (var i = 0; i < result.rows.length; i++) { out.push(result.rows.item(i)); } } callback(out); }}); },/** * query table information * table_name: table name, support % *, */
    showTables: function (table_name, callback) {
      this.fetchAll("select * from sqlite_master where type='table' and name like ?", [table_name], callback);
    },
    /** * assemble query criteria */
    mkWhere: function (data) {
      var arr = [];
      var param = [];
      if (typeof data === 'object') {
        for (var i in data) {
          arr.push(i + "=?");
          param.push(data[i]);
          //console.log('data.i:'+i);}}return {
        sql: arr.join(', '),
        param: param
      };
    },
    onTransactionFail: function (tx, e) {
      showSqliteError(tx);
    },
    /**
     * 错误处理
     */
    onfail: function (tx, e) {
      console.log('sql error: ' + e.message);
      console.log('execute SQL:+ currSql); }}; };// Call initDataBase() to build or open the database
function initDataBase() {
  fgDB = new sqliteDB(dbName, 1024 * 1024 * 2);
  initFGdb();
}
// The contents of the database table
function initFGdb() {
  fgDB.transaction(function (tx) {
    / / the user table
    tx.executeSql('CREATE TABLE IF NOT EXISTS [user] (id VARCHAR2(32) PRIMARY KEY NOT NULL, name VARCHAR2(32), password VARCHAR2(32),phone VARCHAR2(32), remark VARCHAR2(32), define VARCHAR2(32))');
  }, function () {
    console.log('Database created successfully! ');
  }, function (err) {
    console.log('Database creation failed! ');
    console.log(err);
  });
}
Copy the code

conclusion

  • CookieYou can set the expiration time. The storage size is generally4KB; Will be carried inheaderTo communicate with the server
  • localStorageNeed to take the initiative to clean up, otherwise it will always exist; Storage size is5M; Does not participate in server communication
  • sessionStoragelocalStorageSimilar, except that the store is cleared after the page is closed
  • indexedDBNeed to take the initiative to clean up, otherwise it will always exist; There is no limit to the storage size; Does not participate in server communication

Use of storage: now it is not recommended to use cookies to store data, when there is no large amount of data storage needs can use localStorage and sessionStorage, not changed data use localStorage, otherwise use sessionStorage; IndexedDB can be used when there are large data storage requirements.