浏览器数据存储方式

浏览器数据存储方式

常用的前端数据存储方法笼统来说有 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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

『树莓派云台机器人』02. 电脑连接树莓派 配置开发环境

目录 1. 下载ssh交互工具 Xshell 与XFTP(有过相关使用经历的朋友可以跳过这一节内容)2. 下载VNC远程控制工具软件3. 连接过程4. Xshell 命令工具5. XFTP 文件传送工具6. 关于联网总结 欢迎关注 『树莓派云台机器人』 博客,持续更新中 欢迎关注…

基于Zynq的雷达10Gbps高速PCIE数据采集卡方案(三)软件设计

4.1 引言 本章基于第二章的分析结论,进行系统软件设计。软件设计包括逻辑设计、嵌入 式软件设计和上位机软件设计。在逻辑设计中,对 ADC 模块、 Aurora 模块、 DDR3 SDRAM 模块和 PCIE 模块进行分析和设计,在 Vivado 软件提供的 …

在 Linux 上使用 yuzu 模拟 Nintendo Switch 试玩王国之泪

王国之泪5月12日发售,DLC 玩家已经造出各种脑洞大开的东西了,但是买的卡带迟迟没有收到,因此,打算使用 yuzu 模拟器先体验一下 yuzu 是一款开源的 Ninetendo Switch 模拟器,支持在 Linux 或者 Windows 平台运行&#…

vue动态class的写法

本文会详细介绍 vue动态 class的写法,并且提供一些我个人的理解,希望对你有所帮助。 如果你是一个新手,或者想了解 vue的源码,那么首先应该学习 vue的基础知识,比如:什么是静态语言,有什么作用等…

JQuery原理剖析——自己手写简易版JQuery

知其一后知其二; 目录 为什么需要JQuery jQuery的概念: 在此之前回顾JavaScript对象知识: 自己手写的简易JQuery: 为什么需要JQuery 在我们之前写的JS代码中经常会遇见document.getElementById等等获取元素的对象&#xff0c…

Apache Kafka - 重识Kafka生产者

文章目录 概述Kafka 生产者Kafka 生产者工作原理如何使用 Kafka 生产者 生产者配置项(核心)导图总结 概述 Kafka 生产者是 Apache Kafka 中的一个重要组件,它负责将数据发送到 Kafka 集群中。在实时数据处理和流式处理应用程序中&#xff0c…

OKR是什么意思啊

一、OKR是什么意思? OKR是"Objective and Key Results"的缩写,即目标和关键结果。它是一种目标管理框架,旨在帮助组织和团队设定明确的目标,并通过关键结果来衡量和追踪目标的实现情况。 为了让大家快速了解什么是OKR…

Doxygen 源码分析: QCString类

2023-05-20 23:41:56 ChrisZZ imzhuofoxmailcom Hompage https://github.com/zchrissirhcz 文章目录 1. Doxygen 版本2. QCString 类概览3. QCString 特殊成员函数3.1 default 方式的构造函数3.2 单个参数和两个参数的构造函数 4. inline方式实现的成员函数4.1 operator 函数4.…

SQL执行过程

1. select 语句执行过程 一条 select 语句的执行过程如上图所示 1、建立连接 连接器会校验你输入的用户名和密码是否正确,如果错误会返回提示,如果正确,连接器会查询当前用户对于的权限。连接器的作用就是校验用户权限 2、查询缓存 MySQL…

面试字节,过关斩将直接干到 3 面,结果被吊打了?

人人都有大厂梦,对于软件测试员来说,BAT 为首的一线互联网公司肯定是自己的心仪对象,毕竟能到这些大厂工作,不仅薪资高待遇好,而且能力技术都能够得到提升,最关键的是还能够给自己镀上一层金,让…

【自然语言处理】 - 作业1: Word2Vec及TransE实现

课程链接: 清华大学驭风计划 代码仓库:Victor94-king/MachineLearning: MachineLearning basic introduction (github.com) 驭风计划是由清华大学老师教授的,其分为四门课,包括: 机器学习(张敏教授) , 深度学习(胡晓林教授), 计算…

[CTF/网络安全] 攻防世界 view_source 解题详析

[CTF/网络安全] 攻防世界 view_source 解题详析 查看页面源代码方式归类总结 题目描述:X老师让小宁同学查看一个网页的源代码,但小宁同学发现鼠标右键好像不管用了。 查看页面源代码方式归类 单击鼠标右键,点击查看页面源代码: …

国外顶尖高校、企业分享人工智能自学课程英文原课程分享

人工智能无疑已经是当下最火热的方向,在很多领域已经融入我们生活,ChatGPT,Midjourney只是其中一个细分热点。目前这个领域,虽说国内也有不少课程,但是大部分源头还得从英文资料中找。如何学到最新最强得人工智能技能,…

MybatisPlus--基础入门!真滴方便

目录 一、简介 2.特性 二、入门 1.创建springboot 项目(点击查看如何创建 ) 注意&#xff1a;引入 MyBatis-Plus 之后请不要再次引入 MyBatis 以及 MyBatis-Spring&#xff0c;以避免因版本差异导致的问题 2.数据准备 3.配置application.yml 4.代码 BaseMapper<>…

nacos注册中心源码分析一之服务注册、服务心跳

源码分析 nacos客户端注册分析 依赖包 <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency>Nacos的客户端是基于SpringBoot的自动装配实现的 看下依…

Java多线程基础

目录 一、线程的基本使用 &#xff08;一&#xff09;创建线程的两种方式 &#xff08;二&#xff09;线程简单案例&#xff08;Thread&#xff09; 问题&#xff1a;main函数与开启的线程是否是阻塞的&#xff0c;即线程运行时&#xff0c;main函数等待线程运行结束&#…

DOUBLETROUBLE 1

文章目录 DOUBLETROUBLE: 1实战演练一、前期准备1、相关信息 二、信息收集1、nmap探测目标靶机端口2、扫描目标网址目录3、访问网站&#xff0c;发现secret下有个图片4、将图片下载5、查看图片所含内容6、破解密码并查看7、登陆邮箱8、创建反弹shell9、上传反弹shell10、监听11…

失业五个月,终于有offer了!但这家公司的风评惨不忍睹,要接吗?

往年&#xff0c;程序员们找工作可以说是不怎么费力的&#xff0c;不少求职者还会比对几家offer&#xff0c;看薪酬、看加不加班、看通勤时间等等等等&#xff0c;最后选择自己最满意的那一家过去。 但是今年&#xff0c;情况确实完全不一样&#xff0c;用网友的话形容就是“往…

不同厂家对讲机耳塞耳挂/领夹型988对讲机如何写频改频点/频率能互相通信

988型号都是很多厂家代工出来的,代工出来默认的频点都不一样,有可能买回来的2个不同厂家生产的对讲机,这样它们要能通讯,必须要同频点才能互通,它一般出厂设定16个频道,长按+和-键来切换频道。 需要用到typeC 的写频线,其实是用CH430芯片的usb写频线,可以找厂家要写频线…

文件上传之,waf绕过(24)

上传参数名解析&#xff1a;明确哪些东西可以修改 content-disposition:一般可更改 表单的数据 name:表单参数值&#xff0c;不能更改 表单提交的值 filename&#xff1a;文件名&#xff0c;可以修改 上传的文件名 content-type&#xff1a;文件mime&#xff0c;…