Skip to content

一文搞懂浏览器存储

LocalStorage、SessionStorage 合起来称作 WebStorage!

首先宏观分析 cookie 和 WebStorage 之间的区别:3 种:请求携带、属性值、存储容量

1、在请求携带性方面:

  • cookie 数据始终在同源的http 请求中携带(即使不需要),即 cookie 在浏览器和服务器间来回传递
  • sessionStorage 和 localStorage 不会把数据发给服务器,仅在本地保存

2、在属性值方面:

  • cookie 有很多的属性可以进行配置

  • 比如 cookie 有路径(path)的概念,可以限制 cookie 只属于某个路径下,限制作用范围

3、在存储容量方面:

  • 存储大小限制也不同,cookie 数据不能超过 4K,同时因为每次 http 请求都会携带 cookie,所以 cookie 只适合保存很小的数据,如回话标识。

  • webStorage 虽然也有存储大小的限制,但是比 cookie 大得多,可以达到 5M或更大

其次细分比较 cookie 和 LocalStorage、SessionStorage 之间的区别:2 种:有效期和作用域

1、数据的有效期不同

  • sessionStorage:仅在当前的浏览器窗口关闭之前有效;(无法设置特定的过期时间)

  • localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;(无法设置特定的过期时间)

  • cookie:只在设置的 cookie 过期时间之前一直有效,即使窗口和浏览器关闭**(和关闭不关闭窗口没关系!)**

一句话总结:cookie 可以自由设定过期时间,localStorage 是永久存储,sessionStorage 是临时存储

2、作用域不同

  • sessionStorage:不在不同的浏览器窗口中共享,即使是同一个页面;——> 窗口作用域

  • localStorage:在所有同源窗口都是共享的;——> 同源作用域

  • cookie:也是在所有同源窗口中共享的;——> 同源作用域

2.自定义方法给 WebStorage 设置过期时间

localStoragesessionStorage 是浏览器提供的 Web Storage API,它们本身不支持直接设置过期时间。这两种存储方式的数据是永久性的(对于 localStorage)或会话级别的(对于 sessionStorage),在特定条件下会自动过期清除。

如果你需要在本地存储中实现自定义过期时间的功能,你可以结合使用 localStoragesessionStorage 以及 JavaScript 的时间戳或其他方式来手动管理数据的过期时间。以下是一个简单的示例实现 localStorage 的过期时间设置:

js
function setWithExpiry(key, value, expiresInSeconds) {
  const now = new Date();
  const expirationDate = new Date(now.getTime() + expiresInSeconds * 1000);
  const item = {
    //把value设置为一个对象
    value: value, //一个是真实的值
    expires: expirationDate.getTime(), //一个是过期的时间点
  };
  localStorage.setItem(key, JSON.stringify(item));
}

function getWithExpiry(key) {
  const item = JSON.parse(localStorage.getItem(key));
  if (!item) {
    return null;
  }
  const now = new Date();
  if (now.getTime() > item.expires) {
    //看现在的时间是否超过了过期的时间点
    localStorage.removeItem(key);
    return null; //如果过期了返回null
  }
  return item.value;
}

// 设置带过期时间的数据
setWithExpiry("myKey", "myValue", 3600); // 过期时间为 3600 秒

// 获取数据并检查过期
const value = getWithExpiry("myKey");
console.log(value); // 如果在过期时间内,则输出 'myValue',否则为 null

上述示例中,setWithExpiry 函数用于设置带过期时间的数据,它将数据和过期时间存储在 localStorage 中。getWithExpiry 函数用于获取数据并检查过期时间,如果数据已过期,则返回 null。

需要注意的是,上述方法是手动实现过期时间的方式,不同于浏览器原生提供的 localStoragesessionStorage。如果需要更复杂的数据管理和过期时间控制,可能需要考虑使用其他存储方案,如 IndexedDB、Cookies 或服务器端存储。

除了 Cookies、LocalStorage 和 SessionStorage,还有以下几种常见的浏览器中存储数据的方式:

  1. IndexedDB: IndexedDB 是一种在浏览器中存储大量结构化数据的高性能数据库。它提供了一个异步的、基于事件的 API,允许你存储和检索数据。与 Cookies 和 Web Storage 不同,IndexedDB 更适用于存储大量数据,例如应用的缓存、离线数据等。
  2. WebSQL(已废弃): WebSQL 是一种基于 SQL 的浏览器数据库。虽然在某些浏览器中得到了支持,但已经被标记为废弃,因此不推荐在新项目中使用。
  3. Cache API: Cache API 允许开发人员以编程方式存储响应并在离线时检索它们。它主要用于缓存网页资源,以提高离线访问的性能。
  4. CookiesStorage: 这是一个不常见的存储方式,用于存储 Cookies 的 API,与原生的 Cookies 相关联。
  5. LocalStorage 和 SessionStorage 的替代方案: 有一些第三方库和工具,如 Store.js、localForage 等,提供了类似于 LocalStorage 和 SessionStorage 的功能,但可能在一些方面提供更多的特性和选项。

需要根据项目需求选择合适的存储方式。不同的存储方式适用于不同的场景,例如存储少量的键值对、大量结构化数据、缓存资源等。

4.IndexedDB 的用法

**IndexedDB 是一种在浏览器中存储大量结构化数据的高性能数据库。**它提供了一个异步的、基于事件的 API,允许你存储和检索数据。与 Cookies 和 Web Storage 不同,IndexedDB 更适用于存储大量数据,例如应用的缓存、离线数据等。

  1. 打开数据库: 首先,你需要打开一个 IndexedDB 数据库。如果数据库不存在,将会创建一个新的数据库。如果数据库已存在,将会打开现有的数据库。
js
const request = indexedDB.open("myDatabase", 1);

request.onupgradeneeded = (event) => {
  const db = event.target.result;
  const objectStore = db.createObjectStore("myObjectStore", { keyPath: "id" });
  objectStore.createIndex("name", "name", { unique: false }); //myObjectStore可以理解为是数据库的名字,keyPath是主键,name是其他属性
};

onupgradeneeded 事件处理程序中,你可以创建数据库对象存储区(object store)和索引(index)。

  1. 添加数据: 一旦数据库被打开并创建了对象存储区,你可以通过事务将数据添加到对象存储区中。
js
request.onsuccess = (event) => {
  const db = event.target.result;
  const transaction = db.transaction(["myObjectStore"], "readwrite");
  const objectStore = transaction.objectStore("myObjectStore"); //获取数据库操作对象

  const data = { id: 1, name: "John Doe", age: 30 };
  const request = objectStore.add(data);
};
  1. 检索数据: 你可以通过事务从对象存储区中检索数据。
js
request.onsuccess = (event) => {
  const db = event.target.result;
  const transaction = db.transaction(["myObjectStore"], "readonly");
  const objectStore = transaction.objectStore("myObjectStore");

  const getRequest = objectStore.get(1);

  getRequest.onsuccess = (event) => {
    const result = event.target.result;
    console.log(result); // 检索到的数据
  };
};
  1. 更新和删除数据: 你可以通过事务来更新和删除数据。
js
request.onsuccess = (event) => {
  const db = event.target.result;
  const transaction = db.transaction(["myObjectStore"], "readwrite");
  const objectStore = transaction.objectStore("myObjectStore");

  const updateRequest = objectStore.put({
    id: 1,
    name: "Updated Name",
    age: 35,
  });
  const deleteRequest = objectStore.delete(1);
};
  1. 关闭数据库: 在完成数据库操作后,不要忘记关闭数据库。
js
request.onsuccess = (event) => {
  const db = event.target.result;
  db.close();
};

这只是 IndexedDB 的基本用法示例。IndexedDB 还支持更复杂的操作,如索引、游标、范围查询等。由于 IndexedDB 是一个较为复杂的 API,建议参考官方文档或教程以获得更详细的了解。