Beyond Cookies: Today’s client-side data store

By Adam Giese

3. Crazy geek

Original: https://blog.logrocket.com/be…

Reprinted without permission is strictly prohibited

When cookies were first introduced, they were the only way for browsers to store data. Then there are a number of new options: the Web Storage API, IndexedDB, and the Cache API. So is the cookie dead? Let’s take a look at some of these techniques for storing data in a browser.

Cookies

Cookie is a unit of information sent by the server or set on the client and stored in the user’s local browser. They are automatically appended to each request. Because HTTP is a stateless protocol, cookies allow information to be stored on the client side so that additional contextual data can be passed to the server.

Cookies have some flags that are useful for increasing the security of data. The HTTPOnly flag prevents cookies from being accessed with JavaScript, and they can only be accessed when attached to an HTTP request. This is ideal for preventing data leakage through XSS (cross-site scripting) attacks.

In addition, the SECURE flag ensures that cookies are sent only when a request is sent over the HTTPS protocol. The Samesite flag, which can be set to lax or strict (see the difference here), can be used to help prevent CSRF (cross-site request forgery) requests. It tells the browser to send a cookie only if the request is a URL in the same domain as the requester.

When to use cookies?

So, under what circumstances do you want to get a Cookie? One of the most common application scenarios is the authorization token. Samesite protects against CSRF because the HttpOnly flag adds an extra layer of protection for XSS attacks, while Secure ensures that your cookies are encrypted, giving your authentication token an extra layer of protection.

Since the auth token is very small, you don’t have to worry about making a large request. In addition, because they are automatically appended to each request, cookies can be used to determine whether a user is authenticated on the server. This is useful for content rendered by the server, such as when you want to redirect an unauthenticated user to a login page.

Another use of cookies is to store the user’s language code. Since you may want to access the user’s language for most requests, you can take advantage of it to attach automatically.

How to use cookies?

Having discussed the reasons for using cookies, let’s take a look at how you can use them. To Set cookies from the server to the client, add the Set-Cookie header to the HTTP response. Cookies should be in the key=value format. If you were to set cookies in a Node.js application, your code might look something like this:

response.setHeader('Set-Cookie', ['user_lang=en-us', 'user_theme=dark_mode']);

This will set two cookies: it sets user_lang to en-us and user_theme to dark_mode.

Cookies can also be manipulated by the client. To set cookies, you can assign a value to document.cookie in the format of key=value. If the key already exists, it will be overwritten.

document.cookie = 'user_lang=es-es';

If user_lang has been defined, it is now equal to es-es.

You can view all the cookies by accessing the document.cookie value. This returns a list of key-value pairs delimited by semicolons.

document.cookie = 'user_lang=en-us'; document.cookie = 'user_theme=light_mode'; console.log(document.cookie); // 'user_lang=en-us; user_theme=light_mode; '

To increase the accessibility of key-value pairs, we can use the following function to parse this string into an object:

const parseCookies = x => x .split('; ') .map(e => e.trim().split('=')) .reduce((obj, [key, value]) => ({... obj, [key]: value}), {});

If you need to set one of the flags onto your cookie, you can add them after a semicolon. For example, if you’d like to set the Secure and SameSite flags onto your cookie, you would do the following:

If you need to set one of these flags to the cookie, you can add them after the semicolon. For example, if you want to set Secure and Samesite flags on cookies, you can do the following:

Document. The cookie = 'product_ids = 123321; secure; samesite=lax'

Since HttpOnly’s purpose is to make cookies accessible only on the server, it can only be added by the server.

In addition to these security flags, you can also set max-age (the number of seconds a cookie should hold) or Expires (the date the cookie should expire). If none of this is set, the cookie will follow the duration of the browser session. If the user is in incognito mode, the Cookie is deleted when the user session is closed.

Because the interface for handling cookies is not very friendly, you can use a library like js-cookie to make it easier to manipulate them.

Web Storage API

The Web Storage API is a new option for storing data locally. It is added in HTML5, the Web Storage API includes localStorage and sessionStorage. Although cookies typically handle server/client communications, the Web Storage API is best suited for storing client data.

We already have cookies as an option to store data locally, so why do we need Web storage? One reason: Because cookies are automatically added to every HTTP request, the request size can become bloated. So you can use the Web Storage API to store much more data than cookies.

Another advantage is a more intuitive API. If you use cookies, you need to manually parse the cookie string to access the individual keys. Web Storage makes this easier. If you want to set or get values, you can use setItem or getItem.

localStorage.setItem('selected_tab', 'FAQ');
localSTorage.getItem('selected_tab'); // 'FAQ'

Both the key and the value must be strings. If you want to save an object or array, you can do so by calling JSON.stringify() when you save it and JSON.parse() when you read it.

const product = {
  id: '123',
  name: 'Coffee Beans',
};

localStorage.setItem('cached_product', JSON.stringify(product));
JSON.parse(localStorage.getItem('cached_product'));

Another use case for local storage is to synchronize data across multiple tabs. By adding a listener for the ‘storage’ event, you can update the data in another TAB or window.

window.addEventListener('storage', () => {
  console.log('local storage has been updated');
});

This event is fired only when the local or session store is modified in another document. That is, you cannot listen for changes to Storage in the current browser TAB. Unfortunately, as of this writing, store event listeners are not yet supported on Chrome.

So what’s the difference between localStorage and sessionStorage? Unlike cookies, the Web Storage API has no expiration or maximum expiration functionality. If localStorage is used, the data will be retained indefinitely unless deleted manually. You can remove the value of a single key by running localStorage.removeItem(‘key’), or by running localStorage.clear() to clear all data.

If sessionStorage is used, the data will only last until the end of the current session. If you do not set a maximum time or expiration, it will be treated similarly to the way cookies are held. In either case, if the user uses incognito, the local storage does not retain data between sessions.

IndexedDB

If neither cookie nor localStorage meets your requirements, there is another option: IndexedDB, a database system built into the browser.

IndexedDB calls all methods asynchronously when localStorage executes them simultaneously. This will allow access to the data without blocking the rest of the code. This is useful when you’re dealing with large amounts of code that can be expensive to access.

IndexedDB also provides greater flexibility in the types of data it stores. While cookies and localStorage are limited to storing strings, IndexedDB can store any type of data that can be copied through the Structured Cloning Algorithm. This includes Object, Date, File, Blob, RegEx, and more.

The downside of increased performance and flexibility is that IndexedDB’s API is lower level and more complex. Fortunately, there are a number of libraries that can solve this problem.

LocalForAge provides a simpler LocalStorage like API for indexedDB. PouchDB provides an offline storage API that can be synchronized with an online CouchDB database. IDB is a small library with a simpler Promise-based API. Dexie adds a more powerful query API while maintaining good performance. There are many options depending on your usage.

Cache API

Another dedicated tool for persisting data is the Cache API. Although it was originally created for Service Workers, it can be used to cache any network request. The Cache API exposes window. caches, which provides methods to store and retrieve Responses, allowing you to store Requests and Responses pairs that can be accessed forever later.

For example, if you want to check the browser’s cache to get the response before requesting it from the API, you can do the following:

const apiRequest = new Request('https://www.example.com/items');
caches.open('exampleCache') // opens the cache
  .then(cache => {
    cache.match(apiRequest) // checks if the request is cached
      .then(cachedResponse => 
        cachedResponse || // return cachedReponse if available
        fetch(apiRequest) // otherwise, make new request
          .then(response => {
            cache.put(apiRequest, response); // cache the response
            return response;
          })
        })
    .then(res => console.log(res))
})

The first time the code is run, it caches the response. Each subsequent request is cached and no network request is made.

conclusion

Each method of storing data on the browser has its own purpose. If the information is small, sensitive, and likely to be used on the server, then cookies are the best choice. If you want to store larger and less sensitive data, the Web Storage API may be a better choice.

IndexedDB is great if you plan to store a lot of structured data. The Cache API is used to store responses from HTTP requests. There are many tools at your disposal, depending on your needs.

Read additional resources and extensions

You can read the MDN documentation for more information:

  • Web Storage API
  • HTTP cookies
  • IndexedDB API
  • Cache

This article first send WeChat messages public number: front-end pioneer

Welcome to scan the two-dimensional code to pay attention to the public number, every day to push you fresh front-end technology articles

Read on for the other great articles in this column:

  • Deep understanding of Shadow DOM V1
  • Step-by-step tutorial on implementing virtual reality games with WebVR
  • 13 modern CSS frameworks to help you improve your development efficiency
  • Quickly start BootstrapVue
  • How does a JavaScript engine work? Everything you need to know, from the call stack to the Promise
  • WebSocket in action: real-time communication between Node and React
  • 20 interview questions about Git
  • Deep parsing of Node.js console.log
  • What exactly is Node.js?
  • Build an API server with Node.js in 30 minutes
  • A copy of the JavaScript object
  • Programmer 30 years old before the monthly salary is less than 30K, which way to go
  • 14 of the best JavaScript data visualization libraries
  • 8 top VS Code extensions for the front end
  • A complete guide to Node.js multithreading
  • Convert HTML to PDF 4 solutions and implementation

  • More articles…