浏览器数据存储方式

news2024/11/20 10:43:24

浏览器数据存储方式

常用的前端数据存储方法笼统来说有 3 种:

  • local/session storage
  • cookies
  • indexeddb

3 种方法各有各的优点和使用范围。

local/session storage

local/session storage 保存的格式都为键值对,并且用法都是差不多,如下:

const userid = 'u12345';
const user = {
  name: 'name',
  age: 18,
  status: 'active',
};

document.querySelector('#store').addEventListener('click', () => {
  sessionStorage.setItem('userid', userid);
  sessionStorage.setItem('user', user);
});

document.querySelector('#extract').addEventListener('click', () => {
  console.log(sessionStorage);
});

store 被点击后,就会将对应的数据存储到对应的 storage 中:

在这里插入图片描述

需要注意的是,这里的问题就在于 user 没有存进去,这是因为 local/session storage 没有办法存储复杂的对象,而是只能保存字符串,所以正确的保存方式为:

document.querySelector('#store').addEventListener('click', () => {
  sessionStorage.setItem('userid', userid);
  sessionStorage.setItem('user', JSON.stringify(user));
});

document.querySelector('#extract').addEventListener('click', () => {
  console.log(sessionStorage.getItem('userid'));
  console.log(JSON.parse(sessionStorage.getItem('user')));
});

在这里插入图片描述

在这里插入图片描述

local storage 和 session storage 的区别就在于,local storage 相当于做了一个本地的持久化,其中的数据如果不是通过 js 代码、用户删除,浏览器不会主动删除。而 session storage 则是在 session 结束之后(用户关闭当前 tab)后自动删除,如:

在这里插入图片描述

这种存储方法优点是:

  • 可以存储相对比较大的数据(通常来说 5-10mb)

    没记错的话,leetcode 的代码就是存在 local storage 里的

  • 可以根据需求选择使用 session 或是 local

    local storage 存储的数据可以在不同的 tabs 之间被共享

  • 使用方式简单, API 支持更好

这种存储方法缺点是:

  • tabs 之间数据无法共享(针对 session storage)
  • 服务端无法获取数据(除非添加到 header/body 中传输到后端)
  • CORS,不同 domain 之间数据无法共享

cookies

cookies 是另一种存储方式,它存储的也是一个键值对,使用方式如下:

const userid = 'u12345';
const user = {
  name: 'name',
  age: 18,
  status: 'active',
};

document.querySelector('#store').addEventListener('click', () => {
  document.cookie = `uid=${userid}`;
  document.cookie = `user=${JSON.stringify(user)}`;
});

document.querySelector('#extract').addEventListener('click', () => {
  console.log(document.cookie.split(';').map((i) => i.trim()));
});

在这里插入图片描述

在这里插入图片描述

cookies 同样可以设置生存周期,如:

document.cookie = `uid=${userid}; max-age=50`;

这段就会让 cookie 在 50s 后过期:

在这里插入图片描述

另外还有一种 cookie 叫做 httpOnly,这种 cookie 多数用于后端与浏览器之间的交流,无法直接通过 JS 获取。

这种存储方法优点是:

  • 服务端可以获取 cookies

  • 可以用于验证和认证

    虽然这么说,不过因为发起 request 就会携带 cookies,所以大多数情况下 cookies 不会保存敏感信息(病毒代码可以 request 到一些第三方站点,这样会导致数据泄露),只会保留过期时间之类的不是非常敏感的数据

    目前主流代替使用 cookie 的验证方法有 JWT

  • 跨域交流

    这点上面提到了,病毒代码其实是可以携带 cookie 去访问有问题的网页的,不过相对于 local/session 来说,这个的确是优点

  • 可以存活多个 sessions

  • 可用于追踪用户数据

    访问一些网站的话,它们也会“请求”cookies 的数据去“提供更好的服务”

这种存储方法缺点是:

  • 数据量小

    一个 cookie 只有 4kb

  • 多个 cookie 可以导致 HTTP 请求过大

    因为 cookie 会存在于每个请求中

  • 安全、隐私考虑

    包括追踪用户信息和跨域交流,前者是个人信息,后者容易导致 XSS

  • 灵活性低

    不同于 local/session storage,有提供良好的 API 去获取数据,cookies 必须要手动进行 split,在不使用第三方库的情况下获取 cookie 较为麻烦

indexedDB

indexedDB 是这里会提到的最后一个比较主流的数据存储解决方案,但是大多数情况下并不会用到,在我个人的实际项目经验里用到的只有一次:为了提供 offline features。当然,感兴趣的也可以看看 vscode 的源码,我之前有瞄到 vscode 也用 indexedDB。

indexedDB 是一个 NoSQL DB,不过这块这里不会细究。

它的使用方式如下:

const userid = 'u12345';
const user = {
  name: 'name',
  age: 18,
  status: 'active',
};

// non promise based
// will create db if the db doesn't exist, otherwise just open it
const dbRequest = indexedDB.open('StorageDemo', 1);
let db = null;

dbRequest.addEventListener('success', (e) => {
  db = e.target.result;
});

// calls each time when db version changes or initialized
dbRequest.addEventListener('upgradeneeded', (e) => {
  db = e.target.result;
  const objStore = db.createObjectStore('products', {
    keyPath: 'id',
  });

  objStore.transaction.addEventListener('complete', (e) => {
    const productStore = db
      .transaction('products', 'readwrite')
      .objectStore('products');

    productStore.add({ id: 'p1', title: 'First Product', price: 99.99 });
  });
});

dbRequest.addEventListener('error', (e) => {
  console.log(e);
});

document.querySelector('#store').addEventListener('click', () => {
  if (!db) return;

  const productStore = db
    .transaction('products', 'readwrite')
    .objectStore('products');

  productStore.add({ id: 'p2', title: 'Second Product', price: 9.99 });
});

document.querySelector('#extract').addEventListener('click', () => {
  const productStore = db
    .transaction('products', 'readonly')
    .objectStore('products');

  const request = productStore.get('p2');

  request.addEventListener('success', () => {
    console.log(request.result);
  });
});

语法就是这么的麻烦,并且所有的执行都是在 callback 中,同样因为使用太复杂了,所以基本上都会用 wrapper 进行操作,读写的结果如下:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

indexedDB 的优点:

  • 数据存储量大

    据说每个 domain 可以存到 1GB,浏览器可以使用 60% 左右的硬盘内存

  • 存储数据格式灵活

    不需要 stringfy,可以直接以对象、数组的方式存储,同时因为是 NoSQL,所以存储的对象格式也非常灵活

  • 异步操作

    非阻塞式运行(这也是为什么这么多 callbacks)

  • 数据库优势

    包括 ACID、indexed search 和 query

indexedDB 的缺点:

  • 特别麻烦……

    语法麻烦,query 麻烦,异步也麻烦……

    所以也就导致开发麻烦,维护麻烦,而且因为 callbacks 太多了,如果使用 JS 提示不太好,我这里代码就写错了,但是 JS 完全没办法提示:

    在这里插入图片描述

    正确的语法应该使用 objectStore 而不是 objStore (这应该是 VSCode 自动提示,然后我没注意按了 tab 导致的)

  • 浏览器支持问题

    近几年还好,只要不是用 ie

    目前 1.0 的话 IE 还是 partial 支持,2.0 的话 IE 是完全不支持,opera mini 也是完全不支持,除此之外的主流浏览器支持还可以。

  • 缺少原生 query 语言

其他

其他一些就是跨浏览器支持不太好,比如说:

  • web sql,目前 chrome 和 Safari 还是完全不支持

  • private state tokens 是 chrome 自己提出来的实现

  • cache storage 与 service worker 有关,暂时不会涉及到这一部分

  • shared storage 应该也是 chrome 特有的,我在火狐上没看到

    在这里插入图片描述

reference

  • Using HTTP cookies

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/562446.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何选择高品质SPD浪涌保护器

了解了SPD的原理和技术参数和选型方法,但是面对市场上形形色色的SPD品牌,相差无几的参数,该如何去筛选高品质的SPD呢? 作为一个SPD开发人员,谈一下我的看法。前面提到,选择SPD时,有几个重要的参…

探索 Python Web 后端技术的发展之路

导语 Python 在 Web 后端开发领域中有着广泛的应用,它简洁的语法和强大的功能使得开发者们青睐有加。本文将更深入地探讨 Python Web 后端技术的发展趋势和路线,以及相关技术如何影响了 Web 开发的未来。 一、Python Web 框架的演变 Flask&#xff1a…

软件设计师 软件工程

** 判定覆盖 设置判定用例来保障真和假的结果都可以取到** 满足条件覆盖问题问需要多少个测试 ** 其实有技巧的(就看最后面的 分支)** **沟通路径:(n-1)n再/2 和主程序沟通那就是n-1条 ** ******************* 做题技…

HTTPS行为大赏(三分钟了解加密过程)

文章目录 前言1.没有加密的时候2.对称密钥加密传输3.非对称加密4.引入数字证书(对称加密非对称加密) 前言 既然要对HTTPS进行解读,我们首先了解,HTTPS是什么?HTTPS就相当于HTTPSSL/TLS这样的组合,HTTP&…

软考 软件设计师计算机网络笔记

网络设备 物理层的互联设备有中继器和集线器,集线器是一种特殊的多路多端口中继器 数据链路层的互连设备有网桥,交换机,交换机是一个多端口的网桥 网络层互连设备有路由器 协议簇 所有带T的除了TFTP其他都是TCP,所有不带T的除…

BFT 最前线 | ChatGPT登顶App Store;国产中文大语言模型「天河天元」发布;华为招募天才少年;阿里分拆上市

原创 | 文 BFT机器人 AI视界 TECHNOLOGY NEWS 01 ChatGPT上架App Store登顶榜首 OpenAI:很快也将出现在安卓上 近日,ChatGPT正式发布App版本,上架APP Store,支持iPhone和iPad设备。OpenAI表示,ChatGPT iOS APP可免费…

两阶段鲁棒优化及列与约束生成算法(CCG)的基本原理(超详细讲解,附matlab代码)

本文的主要参考文献: Zeng B , Zhao L . Solving Two-stage Robust Optimization Problems by A Constraint-and-Column Generation Method[J]. Operations Research Letters, 2013, 41(5):457-461. 1.两阶段鲁棒优化问题的引入 鲁棒优化是应对数据不确定性的一种优…

探索【Stable-Diffusion WEBUI】的图片超分辨插件:StableSR

文章目录 (零)前言(一)图片放大(二)图片超分辨率放大脚本插件(StableSR)(2.1)下载组件(2.2)使用(2.3)实例对比…

bat脚本语法与实战

一、什么是bat脚本 bat脚本就是将一系列DOS命令按照一定顺序排列而形成的集合,运行在windows命令行环境上。通过本文的学习,基本可以实现一些简单的脚本。 二、为什么学习bat脚本? 使用bat可以提高办公效率,可以直接使用Notepad编…

JavaEE(系列12) -- 常见锁策略

目录 1. 乐观锁和悲观锁 2. 轻量级锁与重量级锁 3. 自旋锁和挂起等待锁 4. 互斥锁和读写锁 5. 可重入锁与不可重入锁 6. 死锁 6.1 死锁的必要条件 6.2 如何避免死锁 7. 公平锁和非公平锁 8. Synchronized原理及加锁过程 8.1 Synchronized 小结 8.2 加锁工作过程 8.2.1 偏向锁…

MySQL保证主备一致,如何解决循环复制?

备库只读,是如何和主库同步数据的? 你可能会问,我把备库设置成只读了,还怎么跟主库保持同步更新呢? 这个问题,你不用担心。因为 readonly 设置对超级 (super) 权限用户是无效的,而用于同步更新…

用Typescript 的方式封装Vue3的表单绑定,支持防抖等功能。

Vue3 的父子组件传值、绑定表单数据、UI库的二次封装、防抖等,想来大家都很熟悉了,本篇介绍一种使用 Typescript 的方式进行统一的封装的方法。 基础使用方法 Vue3对于表单的绑定提供了一种简单的方式:v-model。对于使用者来说非常方便&…

【011】C++选择控制语句 if 和 switch 详解

C控制语句之if和switch语句 引言一、选择控制语句if1.1、if 语句的形式1.2、if...else...语句的形式1.3、if...else if... else...语句 二、选择控制语句switch2.1、switch语句形式 三、switch和if...else if...else...比较四、注意事项总结 引言 💡 作者简介&#…

企业工程行业管理系统源码-专业的工程管理软件-提供一站式服务

Java版工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离 功能清单如下: 首页 工作台:待办工作、消息通知、预警信息,点击可进入相应的列表 项目进度图表:选择(总体或单个)项目显示1…

Doo Prime 德璞资本:期货开户条件全解析!让你不再困惑!

期货市场是金融市场中一个非常重要的部分,对于许多投资者来说,期货市场是一个非常有吸引力的投资选择。然而,要进行期货交易,必须首先开设期货账户,这就需要满足一些期货开户条件,因此本文将介绍期货开户条…

认识SpringCloud(一) 注册中心Eureka

Spring Cloud 封装了 Netflix 公司开发的 Eureka 模块来实现服务治理。在传统的rpc远程调用框架中,管理每个服务与服务之间依赖关系比较复杂,管理比较复杂,所以需要使用服务治理,管理服务于服务之间依赖关系,可以实现服…

(原创)getX+Dio实现Flutter悬浮置顶的页面效果

前言 Flutter的开发相对已经比较成熟了,现在市面上不少商业应用也在使用这个技术 老实说,Flutter去实现一些基础的ui界面,效率还是很高的 当然前提是你对它要有一定的了解。 今天就演示一下,如何去实现一个基础悬浮置顶的页面效果…

OSTrack 中的边界框回归策略

目录 一、裁剪和标签的设置 二、模型的预测输出的边界框回归 一、裁剪和标签的设置 1、添加偏移量,得到偏移后的边界框 jittered_anno [self._get_jittered_box(a, s) for a in data[s _anno]] 2、以偏移后的边界框为中心,进行裁剪 首先以偏移边界…

Apache Pulsar入门指南

1.概述 Apache Pulsar 是灵活的发布-订阅消息系统(Flexible Pub/Sub messaging),采用计算与存储分离的架构。雅虎在 2013 年开始开发 Pulsar ,于 2016 年首次开源,目前是 Apache 软件基金会的顶级项目。Pulsar 具有支…

面试官:写一个单例模式

1. 什么是单例模式 了解单例模式之前,我们需要先了解什么是设计模式。 设计模式是一种抽象的编程思想,不局限于编程语言,简单来说,就是一些大佬程序猿针对一些典型的场景,给出一些典型的解决方案,只要按照这…