A cookie

1.1 The birth of cookie

Since the HTTP protocol is stateless, the business on the server side must be stateful. The original purpose of cookies was to store state information in the Web for easy use on the server side. Such as determining whether a user is visiting the site for the first time. The most recent specification is RFC 6265, which is a collaborative implementation of the browser server.

1.2 the cookie mechanism

When a user visits and logs in a website for the first time, the setting and sending of cookies will go through the following four steps:



The first request to write a cookie



Bring cookies with you next time



1.3 Cookie access

1.3.1 Setting cookies:

document.cookie = newCookie;
// document.cookie = "name=value; domain=www.mydomain.com; path=/; expires=Tue, 01 Sep 2020 07:29:10 GMT; HttpOnly; secure";
Copy the code
  • key=valueKey value pairs (mandatory).
  • ; path=pathIf not defined, the default is the path to the current document location. /” indicates that all paths can be used.
  • ; domain=domainThe domain name that generated the Cookie, if not defined, defaults to the domain part of the path to the current document location. Contrary to the earlier specification, putting a. Character before a domain name will be ignored because browsers may refuse to set such cookies. If a field is specified, subfields are included.
  • ; max-age=max-age-in-seconds
  • ; expires=date-in-GMTString-formatIf not defined, the cookie will expire at the end of the conversation.Date.toUTCString() 
  • ; secureIf this property is set, the Cookie will only be returned during an SSH connection.

The cookie value string can be guaranteed to not contain any commas, semicolons, or Spaces with encodeURIComponent() (cookie values disallow these values).

1.3.2 modify the cookie

If you set the new value directly, the old value will be overwritten.

1.3.3 deleting cookies

Simply set the Expires parameter to the previous time. For example, Thu, 01 Jan 1970 00:00:00 GMT.

document.cookie = "name=; expires=Thu, 01 Jan 1970 00:00:00 GMT";
Copy the code

1.4 the cookie framework

As a formatted string, the value of a cookie is sometimes difficult to process naturally. The purpose of the library below is to simplify obtaining document.cookies by defining a partially consistent object (docCookies) for Storage objects. It provides full Unicode support.

/*\ |*| |*| :: 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() |*| \*/

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]); }
    returnaKeys; }};Copy the code

Example usage:

docCookies.setItem("test0"."Hello world!");
docCookies.setItem("test1"."Unicode test: \u00E0\u00E8\u00EC\u00F2\u00F9".Infinity);
docCookies.setItem("test2"."Hello world!".new Date(2020.5.12));
docCookies.setItem("test3"."Hello world!".new Date(2027.2.3), "/blog");
docCookies.setItem("test4"."Hello world!"."Sun, 06 Nov 2022 21:43:15 GMT");
docCookies.setItem("test5"."Hello world!"."Tue, 06 Dec 2022 13:11:07 GMT"."/home");
docCookies.setItem("test6"."Hello world!".150);
docCookies.setItem("test7"."Hello world!".245."/content");
docCookies.setItem("test8"."Hello world!".null.null."example.com");
docCookies.setItem("test9"."Hello world!".null.null.null.true);
docCookies.setItem("test1; ="."Safe character test; =".Infinity);
 
alert(docCookies.keys().join("\n"));
alert(docCookies.getItem("test1"));
alert(docCookies.getItem("test5"));
docCookies.removeItem("test1");
docCookies.removeItem("test5"."/home");
alert(docCookies.getItem("test1"));
alert(docCookies.getItem("test5"));
alert(docCookies.getItem("unexistingCookie"));
alert(docCookies.getItem());
alert(docCookies.getItem("test1; ="));
Copy the code

1.5 Session and the relationship between cookies and session

session

The Session is stored on the server. In order to obtain higher access speed, the server generally stores the Session in memory, and each user has an independent Session. If the contents of the Session are too complex, when a large number of users access the server, it may cause memory overflow, so our Session contents should be properly simplified.



When we access the server for the first time, the server will automatically create a Session for us. After the Session is generated, the server will update the last access time of the Session as long as the user continues to access the server, and maintain the Session. When a user accesses the server once, regardless of whether the session is read or written, the server considers the session active once. As more and more users access our server, our sessions will grow. To prevent memory overflow, the server deletes sessions that have not been active for a long time. This is the session timeout period, after which our session will automatically expire.







HTTP is a stateless protocol, every time a customer reads a Web page, the server opens a new session, and the server does not automatically maintain the customer’s context information, so how to implement the shopping cart in the online store, session is a mechanism to save context information, it is for every user, The value of the variable is stored on the server side, the session is based on cookies or URL rewriting, the default is cookies, the server sends a cookie to the client browser called JSESSIONID and the value of JSESSIONID is SessionID, A session uses the SessionID to identify different client identities.

The relationship between cookies and sessions



Two localStorage

The read-only localStorage property allows you to access a Document source (Origin) object Storage; The stored data is saved in the browser session. LocalStorage is similar to sessionStorage, but the difference lies in that: Data stored in localStorage can be retained for a long time. When the page session ends — that is, when the page is closed, the data stored in sessionStorage is erased. LocalStorage distinguishes protocol storage, example.com/ and https://ex…

2.1 use localStorage

localStorage.setItem('myCat'.'Tom');

let cat = localStorage.getItem('myCat');

localStorage.removeItem('myCat');

// Remove all
localStorage.clear();
Copy the code

Three sessionStorage

The sessionStorage property allows you to access a sessionStorage object corresponding to the current source. It is similar to localStorage except that data stored in localStorage does not have an expiration date, while data stored in sessionStorage is cleared when the page session ends.

  • The page session remains as long as the browser is open, and the original page session remains when the page is reloaded or restored.
  • The top-level browsing session context is copied as the context for the new session when a new TAB or window opens a page, unlike session cookies.
  • Opening multiple Tabs pages with the same URL creates their ownsessionStorage.
  • Close the corresponding browser TAB to clear the correspondingsessionStorage.

SessionStorage is also a protocol-specific storage. SessionStorage in example.com/ and example.com/ is independent.

3.1 sessionStorage use

// Save data to sessionStorage
sessionStorage.setItem('key'.'value');

// Get data from sessionStorage
let data = sessionStorage.getItem('key');

// Delete saved data from sessionStorage
sessionStorage.removeItem('key');

// Delete all saved data from sessionStorage
sessionStorage.clear();
Copy the code

Four IndexDB

IndexDB is a transactional database system that runs in a browser and is used to store large amounts of structured data (including file/binary Large objects (Blobs)) on the client side. Theoretically, IndexDB has no storage upper limit (generally no less than 250MB).

Note: This feature is available in Web Workers.

4.1 IndexDB characteristics

  1. IndexedDB uses an object Store internally to store data. All types of data can be stored directly, including JavaScript objects. In the object warehouse, data is stored as “key-value pairs”. Each data record has a corresponding primary key. The primary key is unique and cannot be duplicated, otherwise an error will be thrown.
  2. Asynchronous IndexedDB operations do not lock the browser and users can still perform other operations, in contrast to LocalStorage, which operates synchronously. Asynchronous design is designed to prevent massive data reads and writes from slowing down the performance of a web page.
  3. Support for Transactions IndexedDB supports transactions, which means that if one of the steps fails, the entire transaction is cancelled and the database is rolled back to the state before the transaction occurred, without overwriting only a portion of the data.
  4. The IndexedDB is subject to the same origin restriction, with each database corresponding to the domain name that created it. Web pages can only access databases under their own domain names, but not cross-domain databases.
  5. IndexedDB has a much larger storage space than LocalStorage, usually no less than 250MB or even no upper limit.
  6. Support binary storage IndexedDB can store not only strings but also binary data (ArrayBuffer objects and Blob objects).

4.2 IndexDB use

1 Open/create an IndexDB database (if the database does not exist, the open method creates a new database directly).

let db
// Parameter 1 is the database name, and parameter 2 is the version number
const request = window.indexedDB.open("exampleDB".1)
request.onerror = function(event) {
  console.log('IndexDB cannot be used')
}
request.onsuccess  = function(event){
  db = event.target.result
  console.log("IndexDB opened")}Copy the code

2 Create an Object Store.

The // onupgradenneeded event is called when an update has occurred to the initial database/version
request.onupgradeneeded = function(event){
  let objectStore
  if(! db.objectStoreNames.contains('test')) {
    objectStore = db.createObjectStore('test', { keyPath: 'id'}}})Copy the code

Build a transaction to perform some database operations, such as adding or extracting data.

// Create a transaction and specify the table name and read/write permissions
const transaction = db.transaction(["test"]."readwrite")
// Get the Object Store
const objectStore = transaction.objectStore("test")
// Write data to the table
objectStore.add({id: 1.name: 'name1'})
Copy the code

4 Wait for the operation to complete by listening for the right type of event.

transaction.oncomplete = function(event) {
  console.log("Operation successful", event)
}
transaction.onerror = function(event) {
  console.log("Operation failed", event)
}
Copy the code

To compare

classification The life cycle Storage capacity Storage location
cookie By default, it is stored in memory and will expire when the browser closes. (If the expiration time is set, it will expire after the expiration time is reached.) 4KB Save it on the client side and bring it with you on every request
localStorage Theoretically permanent unless actively removed. 4.98MB (different browsers, Safari 2.49 MB) Save to the client and do not interact with the server. Save Network Traffic
sessionStorage This parameter is valid only in the current web session and will be cleared after you close the page or browser. 4.98MB (no limit in some browsers) Same as above
IndexDB Theoretically permanent unless actively removed. Basic unrestricted Same as above

Summary: Because every HTTP request carries cookie information, it wastes bandwidth and has large capacity limits, so cookies should be used as little as possible. LocalStorage and sessionStorage depend on whether permanent storage is required.

compatibility

Cookies are basically supported.

LocalStorage and sessionStorage browser support:



Methods to check whether support is supported:

Type ='localStorage' or type='sessionStorage'
function storageAvailable(type) {
    var storage;
    try {
        storage = window[type];
        var x = '__storage_test__';
        storage.setItem(x, x);
        storage.removeItem(x);
        return true;
    }
    catch(e) {
        return e instanceof DOMException && (
            // everything except Firefox
            e.code === 22 ||
            // Firefox
            e.code === 1014 ||
            // test name field too, because code might not be present
            // everything except Firefox
            e.name === 'QuotaExceededError' ||
            // Firefox
            e.name === 'NS_ERROR_DOM_QUOTA_REACHED') &&
            // acknowledge QuotaExceededError only if there's something already stored(storage && storage.length ! = =0); }}Copy the code

The resources

  • [1] MDN-document.cookie
  • [2] MDN-Window.localStorage
  • [3] MDN-window.sessionStorage
  • [4] MDN- Using the Web Storage API
  • [5] Nuggets – Kuaiguo Taxi front-end team – Comparison and summary of several Web data storage methods: localStorage, sessionStorage, Cookie and session
  • [6] Ruan Yifeng’s Weblog on IndexedDB
  • [7] Mining – Local Storage – Cookies to Web Storage, IndexDB
  • [8] The difference between Cookie and session and the life cycle of session
  • [9] Zhihu-Cookie and session should be understood in this way