您当前的位置:首页 > 电脑百科 > 程序开发 > 编程百科

Web 存储技术

时间:2019-07-08 10:24:39  来源:  作者:

一、背景介绍

第一个Web存储的技术叫做Cookie,它是网站的身份证。是网站为了辨别用户身份,进行session(服务端的session)跟踪而存储在用户本地终端上的数据,也就是说它是存在电脑硬盘上的,一个很小的txt类型的文件。Cookie每次都会跟随http请求发送到服务端,也就是说每一个http请求都会带上我们的cookie数据,因此它存在一个安全性的问题。

cookie本身也是有很大的局限性的,首先它很小,主流的浏览器最大支持 4096 字节,除了最大字节的限制,每个网站的cookie个数(也就是每一个first每一个域)也是有限制的,一般浏览器是20个。除此之外,cookie还会默认跟随所有http请求发送,即使不需要使用这个cookie来鉴别用户但是它也是会跟随http请求发送的,这样就会造成一个网络资源的浪费。然后部分的浏览器还限制了总的cookie个数300个。

在cookie的诸多局限性下,Web Storage应运而生。Web Storage 解决了很多问题:

比如它支持存储大量数据,支持复杂的本地数据库,而且也不会默认跟随http请求。Web Storage主要是有四个:

  • SessionStorage
  • LocalStorage
  • WebSQL
  • indexedDB

二、Cookie的简单介绍

Cookie是html4的一个标准,它一般不需要考虑兼容。它是网站的一个身份证,服务器可以针对不同用户,做出不同的响应。cookie存储在用户的机器上是一个纯文本,就是一个txt文件并不是一个脚本,它不能执行东西只负责记录。浏览器每次请求都会带上当前网站的cookie。

Cookie分为两种类型,一种呢是会话cookie,也就是临时性的cookie,退出浏览器或者是关闭即删除;

另一种叫持久cookie,它会一直存在,存在的时间由特定的过期时间或者是有效期来决定。

Cookie的域 Domain决定了当前的一个cookie的权限,哪一个域可以使用这个cookie。

Cookie的路径 Path,下面一个简单的例子:

www.baidu.com id="123456" domain="www.baidu.com"
www.baidu.com/user id="123456" user="eric" domain="www.baidu.com" path="/user/"
​
www.baidu.com/search id="123456";
www.baidu.com/user/search id="123456" user="eric";

如上www.baidu.com设置了一个id等于123456,domain是www.baidu.com,然后另外一个跟第一个一样多设置了一个user,id相同,但是多了一个user=“Eric”,它的domain设置成了www.baidu.com,path就到了user下面。这两者设置完成之后,当我们访问www.baidu.com/search时百度只能拿到id,因为user="Eric"是属于user这个域下面的,也就是说在search下面是获取不到的,但是在www.baidu.com/user/search这个时候我们就可以获取到名叫Eric的user。Path也是一种权限的控制只是相较于域domain是低一级的。

Cookie的安全secure,如果这个属性为TRUE,那么网站只有在https的请求下面才会携带当前的cookie。

Cookie的HttpOnly这个属性如果为TRUE,那么就不允许JAVAScript操作cookie。

因为cookie是存储在客户端一个独立的文件,因此服务器是无法分辨用户和攻击者的。关于cookie的目的分为两种:一种是跨站点脚本攻击,一种是跨站请求伪造。

三、SessionStorage

key-value的键值对,是HTML5新增的一个会话存储对象。

SessionStorage是临时保存在同一窗口,也就是同一标签页的数据。如果当前标签页关闭了,那么SessionStorage也就失效了。这也是SessionStorage最显著的一个特点:单页标签限制。

除此之外,它还有的一些特点有:

  • 同源策略,也就是在同一协议,同一主机名和同一端口下的同一tab
  • 只在本地存储,不会跟随http请求发送到服务器
  • 存储方式采用key-value键值对,这里面的value只能存字符串类型,如果存其他的会自动转换成字符串。
  • 存储上线限制达到了5MB,如果当前存储超出上限新的内容会把旧的内容覆盖但不会报错。

属性:

  • sessionStorage.length - 键值对数量
  • sessionStorage.key(int index) -> null
  • sessionStorage.getItem(string key) -> null
  • sessionStorage[string key]
  • sessionStorage.setItem(string key, string value)
  • sessionStorage.removeItem(string key)
  • sessionStorage.clear()

Json对象

  • JSON.stringify()
  • JSON.parse()

四、LocalStorage

LocalStorage也是在浏览器的Application下面有一个Local Storage,它和SessionStorage是十分相似的,同样是key-value键值对,也是HTML5的新增存储对象,它与SessionStorage的特点不同之处在于没有标签页的限制和在浏览器的无痕模式下LocalStorage是不允许读取的,永久性的存储,然后SessionStorage超出限制是覆盖不会报错而LocalStorage超出会报错。

特点**:

  • 同源策略,也就是在同一协议,同一主机名和同一端口下的同一tab
  • 没有标签页的限制
  • 只在本地存储,不会跟随http请求发送到服务器
  • 存储方式采用key-value键值对,这里面的value只能存字符串类型,如果存其他的会自动转换成字符串。
  • 存储上线限制达到了5MB,如果当前存储超出上限会报错。
  • 无痕模式下不可读取
  • 永久性存储

属性:

  • sessionStorage.length - 键值对数量
  • sessionStorage.key(int index) -> null
  • sessionStorage.getItem(string key) -> null
  • sessionStorage[string key]
  • sessionStorage.setItem(string key, string value)
  • sessionStorage.removeItem(string key)
  • sessionStorage.clear()

注意事项:LocalStorage和SessionStorage在web view是不可靠的,web view指的是在开发混合APP的时候使用了浏览器来实现我们的APP,这个时候是不可靠的,因为在浏览器崩溃的情况下数据可能没有存进去。

另外一个在IOS浏览器中不可重复setItem,如果重复会报错,然后这个时候我们需要先removeItem再添加item。

监听storage的变化

监听storage包括SessionStorage和LocalStorage。然后这里需要提到两个概念:同源和监听同源网页。

  • 同源:协议、域名、端口三者相同,同源的情况下我们可以共享SessionStorage和LocalStorage。
  • 同源策略还禁止不同源执行任何脚本。
http://localhost:63342/simpleApp/app/index.html#/
(协议) (域名) (端口) (路径)
  • 监听同源网页,但是同一网页是无效的
window.addEventListener("storage", function (event) {
 console.log(event.key);
 console.log(event.oldValue);
 console.log(event.newValue);
 console.log(event.url);
 console.log(event.storageArea);
});

五、IndexedDB

IndexedDB 背景

  • Storage(Storage指的是SessionStorage和LocalStorage)不适合存储大量的数据
  • Storage不能提供搜索功能
  • Storage不能建立索引,存储的内容也比较少
  • IndexedDB扩大了web存储的容量,可以达到250MB以上

基本概念

首先它是一个NoSQL,也就是一个非关系型数据库。MySQL和Oracle都是关系型数据库。意思就是说如果建立了两个表在关系型数据库里面我们可以通过一个外链把多个表联系起来,但是NoSQL不行,在NoSQL里面如果想要多个表关联起来,我们只能手动的在关联的表里面添加上需要关联的另外一个或多个表的id。这是NoSQL与MySQL两者之间的一个区别。

IndexedDB的特点也是和Storage是一样的:

  • 键值对储存 ,但是允许所有类型,不允许主键重复报错
  • 是一个异步操作, 不阻塞浏览器线程
  • 支持事务,事务是SQL数据库的一个概念,也就是说我们进行任何的增删改查都要在某一个事务下面进行,提供了一个回滚功能,一系列操作有一步失败, 数据库回滚到事务发生之前的状态,这样为了避免操作中途出现失败,影响整个数据库的状态
  • 同源限制
  • 支持二进制储存

IndexedDB几个基本概念:

  • IDBDatabase - 数据库
  • IDBObjectStore - 对象仓库
  • IDBIndex - 索引
  • IDBTransaction - 事务
  • IDBRequest - 操作请求
  • IDBCursor - 指针
  • IDBKeyRange - 主键集合

IndexedDB浏览器兼容

Web 存储技术

 

IDBDatabase

IDB是IndexedDB的缩写,它呢就是数据库,数据库也叫作数据的一个容器。每一个源(同源策略)可以建立很多数据库。Database有一个版本的概念,版本对应着数据库表,同一时刻只能存在一个版本。比如:新增一个表,然后我们需要把database的版本加一,表里面要新增一列,这时同样需要把数据库版本加一。

注意:1 同一时刻只能有一个版本存在

​ 2 修改数据库结构只能通过升级数据库版本

  • 打开数据库
/* databaseName不存在则创建 */
/* version为整数, 新建时为1 */
​
let database;
let userStore;
const request = window.indexedDB.open(databaseName, version);
​
/* 成功打开数据库 */
request.onsuccess = event => {
 database = request.result;
}
​
/* 打开数据库失败 */
request.onerror = error => {
 console.log(error);
}
​
/* 版本号大于当前数据库版本 */
request.onupgradeneeded = event => {
 database = event.target.result;
}

注意:如果在打开数据库时,数据库不存在,将会新建一个

IDBObjectStore(数据库表)

创建表,最好是在upgradeneeded下执行;在创建数据库表的时候需要指定主键,主键代表了唯一的标识,比如 keyPath:‘id’;如果不指定主键,我们可以指定一个autoIncrement:true,自增的一个概念,也就是不指定主键数据库会自动添加主键而且这个主键就是数字,依次递增的。

const createStore = () => {
 //如果当前的objectStoreNames.contains包含user,如果不包含user这个表,然后就用这个database.createObjectStore创建了一个表,这个表的名字就叫做user,然后主键就是下面的id
 if(!db.objectStoreNames.contains('user')) {
 userStore = database.createObjectStore('user', { keyPath: 'id' });
 }
}

指定索引:

const createStore = () => {
 if(!database.objectStoreNames.contains('user')) {
 userStore = database.createObjectStore('user', { keyPath: 'id' });
 userStore.createIndex('name', 'name', { unique: true });
 }
}

IDBTransaction(事务)

创建完之后需要往里面添加数据,添加数据我们就需要使用到事务。

事务涉及到数据库的增删改查,它有三个状态:

  • complete
  • error
  • abort

属性:

  • IDBTransaction.db 当前数据库
  • IDBTransaction.mode 模式,使用模式分为readonly和readwrite
  • IDBTransaction.objectStoreNames 当前数据库涉及到的哪几个数组表
  • IDBTransaction.error 回调

数据库的基本操作:增删改查以及清空。

新增数据(add)

分为两种情况:一种是使用自增的数据库的id或者是自增的一个键值,如果已经创建主键,那么新增必须包含主键和另一种已创建主键但主键不可重复。

const add = () => {
 /* 创建事务 */
 /* 使用某个数据库 */
 /* add新增 */
 transactionRequest = database.transaction(['user'], 'readwrite')
 .objectStore('user')
 .add({ id: 100, name: 'Eric', age: 28, email: 'Ericlee00@163.com' });
​
 /* 成功 */
 transactionRequest.onsuccess = event => {
 console.log('数据写入成功', event);
 };
​
 /* 失败 */
 transactionRequest.onerror = error => {
 console.log('数据写入失败', error);
 }
}

读取数据(get)

const read = () => {
 /* 创建事务 */
 transaction = database.transaction(['user']);
 /* 选择数据库表 */
 table = transaction.objectStore('user');
 /* 读取数据 */
 transactionRequest = table.get(2);
​
 /* 成功 */
 transactionRequest.onerror = event => {
 console.log('数据读取失败', event);
 };
​
 /* 失败 */
 transactionRequest.onsuccess = event => {
 if (transactionRequest.result) {
 console.log('数据读取成功', transactionRequest.result);
 } else {
 console.log('未读取到数据');
 }
 };
}

更新数据(put)

更新不存在的数据时会新建,也就是说在新增数据时如果相同,往往会出错,但是在更新数据时不会出错。如果数据不存在就会新建,如果存在就会一直更新。

const update = () => {
 transactionRequest = database.transaction(['user'], 'readwrite')
 .objectStore('user')
 .put({ id: count, name: 'David', age: 35, email: 'David@xiakedao.com' });
​
 transactionRequest.onsuccess = function (event) {
 console.log('更新数据成功', event);
 };
​
 transactionRequest.onerror = error => {
 console.log('更新数据失败', error);
 }
 }

删除数据(delete)

const delete = () => {
 transactionRequest = database.transaction(['user'], 'readwrite')
 .objectStore('user')
 .delete(2);
​
 transactionRequest.onsuccess = function (event) {
 console.log('删除数据成功', event);
 };
​
 transactionRequest.onerror = error => {
 console.log('删除数据失败', error);
 }
 }

清空数据(clear)

IDBCursor(指针)

提供了一种遍历数据的可能。

const readAll = () => {
 table = database.transaction('user').objectStore('user');
​
 table.openCursor().onsuccess = () => {
 let cursor = event.target.result;
​
 if (cursor) {
 console.log('数据遍历', cursor);
 cursor.continue();
 } else {
 console.log('数据遍历完成');
 }
 };
 }

关闭IndexedDB数据库连接

const closeDataBase = () => {
 database.close();
}

删除IndexedDB数据库前,须先关闭数据库连接

const deleteDataBase = () => {
 indexedDB.deleteDatabase('first_database');
}

六、WebSQL

基本概念:并不是 HTML5 的规范 , 只能算是一个独立的规范;使用WebSQL是完完全全的SQL 语句,使用SQL语句来操作客户端数据库;它一共有三个比较重要的概念,分别是:openDatabase 打开数据库,可以是使用现有数据库或者新建数据库;transaction 事务,所有的数据库都支持事务;executeSql 执行SQL语句。

openDatabase(打开数据库)

相比于IndexedDB的概念稍微多一点,主要是有数据库名称、版本号(在IndexedDB里面版本号都是整数,但是在WebSQL里面它可以是小数)、描述文本(介绍数据库是干什么的)、数据库大小和创建回调(function,只在第一次创建的时候才会调用)。

const database = openDatabase('my_database', '1.0', 'first', 2 * 1024 * 1024, function() {
​
});

Transaction(事务)

  • 创建表
const createTable = () => {
 database.transaction(function (content) { 
 content.executeSql('CREATE TABLE IF NOT EXISTS USER (id unique, name)');
 });
}
  • 添加数据
const addData = () => {
 database.transaction(function (content) { 
 content.executeSql('INSERT INTO USER (id, name) VALUES (1, "Eric")');
 });
}
  • 查询数据
const searchData = () => {
 database.transaction(function (content) { 
 content.executeSql('SELECT * FROM USER');
 });
}
  • 更新数据
const updateData = () => {
 database.transaction(function (content) { 
 content.executeSql('UPDATE USER SET name='David' WHERE id=1');
 });
}
  • 删除数据库表
const deleteDataBase = () => {
 database.transaction(function (content) { 
 content.executeSql('DROP TABLE USER');
 });
 }


Tags:Web   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
在互联网的江湖里头,每天都有新鲜事。我们昨天还在聊元宇宙,还没有了解元宇宙是个啥,今天又开始了web3.0,站在时代的浪潮之巅,哪怕我们只是一滴最普通的水,也会随着巨浪此起彼伏,直...【详细内容】
2021-12-24  Tags: Web  点击:(7)  评论:(0)  加入收藏
近日只是为了想尽办法为 Flask 实现 Swagger UI 文档功能,基本上要让 Flask 配合 Flasgger, 所以写了篇 Flask 应用集成 Swagger UI 。然而不断的 Google 过程中偶然间发现了...【详细内容】
2021-12-23  Tags: Web  点击:(6)  评论:(0)  加入收藏
我们有时候在音频通话过程中,想要改成视频通话。如果挂断当前的通话再重新发起视频通话就会显得比较麻烦。 因此很多app提供了将音频通话升级成视频通话的功能,同时也有将视频...【详细内容】
2021-12-23  Tags: Web  点击:(5)  评论:(0)  加入收藏
你好,这里是科技前哨。 随着“元宇宙”概念的爆火,下一代互联网即将到来,也成了互联网前沿热议的话题,12月9日美国众议院的听证会上,共和党议员Patrick McHenry甚至宣称,要调整现...【详细内容】
2021-12-17  Tags: Web  点击:(14)  评论:(0)  加入收藏
一、SQL注入漏洞SQL 注入攻击( SQL Injection ),简称注入攻击、SQL注入,被广泛用于非法获取网站控制权,是发生在应用程序的数据库层上的安全漏洞。在设计程序,忽略了对输入字符串...【详细内容】
2021-12-10  Tags: Web  点击:(23)  评论:(0)  加入收藏
今天详解一个 Python 库 Streamlit,它可以为机器学习和数据分析构建 web app。它的优势是入门容易、纯 Python 编码、开发效率高、UI精美。 上图是用 Streamlit 构建自动驾驶...【详细内容】
2021-12-09  Tags: Web  点击:(24)  评论:(0)  加入收藏
对于一个新建连接,内核要发送多少个 SYN 连接请求才决定放弃。不应该大于255,默认值是5,对应于180秒左右时间。。(对于大负载而物理通信良好的网络而言,这个值偏高,可修改为2.这个值仅仅是针对对外的连接,对进来的连接,...【详细内容】
2021-12-08  Tags: Web  点击:(23)  评论:(0)  加入收藏
10月18号, W3C中网络平台孵化器小组(Web Platform Incubator Community Group)公布了HTML Sanitizer API的规范草案。这份草案用来解决浏览器如何解决XSS攻击问题。 网络安全中...【详细内容】
2021-12-07  Tags: Web  点击:(20)  评论:(0)  加入收藏
【网络通信 -- WebRTC】WebRTC 基础知识 -- ICE 交互总结【1】ICE 的一般概念简介ICE 角色offer (主动发起)的一方为 controlling 角色answer (被动接受)的一方为 controlle...【详细内容】
2021-11-30  Tags: Web  点击:(24)  评论:(0)  加入收藏
来源:AirPython作者:星安果 1. 前言大家好,我是安果!之前推荐过很多优秀的 Web 自动化工具,比如:Selenium、Helium、Cypress、Pyppeteer 等利用它们实现自动化的前提是必须安装依...【详细内容】
2021-11-30  Tags: Web  点击:(31)  评论:(0)  加入收藏
▌简易百科推荐
本文分为三个等级自顶向下地分析了glibc中内存分配与回收的过程。本文不过度关注细节,因此只是分别从arena层次、bin层次、chunk层次进行图解,而不涉及有关指针的具体操作。前...【详细内容】
2021-12-28  linux技术栈    Tags:glibc   点击:(3)  评论:(0)  加入收藏
摘 要 (OF作品展示)OF之前介绍了用python实现数据可视化、数据分析及一些小项目,但基本都是后端的知识。想要做一个好看的可视化大屏,我们还要学一些前端的知识(vue),网上有很多比...【详细内容】
2021-12-27  项目与数据管理    Tags:Vue   点击:(2)  评论:(0)  加入收藏
程序是如何被执行的  程序是如何被执行的?许多开发者可能也没法回答这个问题,大多数人更注重的是如何编写程序,却不会太注意编写好的程序是如何被运行,这并不是一个好...【详细内容】
2021-12-23  IT学习日记    Tags:程序   点击:(9)  评论:(0)  加入收藏
阅读收获✔️1. 了解单点登录实现原理✔️2. 掌握快速使用xxl-sso接入单点登录功能一、早期的多系统登录解决方案 单系统登录解决方案的核心是cookie,cookie携带会话id在浏览器...【详细内容】
2021-12-23  程序yuan    Tags:单点登录(   点击:(8)  评论:(0)  加入收藏
下载Eclipse RCP IDE如果你电脑上还没有安装Eclipse,那么请到这里下载对应版本的软件进行安装。具体的安装步骤就不在这赘述了。创建第一个标准Eclipse RCP应用(总共分为六步)1...【详细内容】
2021-12-22  阿福ChrisYuan    Tags:RCP应用   点击:(7)  评论:(0)  加入收藏
今天想简单聊一聊 Token 的 Value Capture,就是币的价值问题。首先说明啊,这个话题包含的内容非常之光,Token 的经济学设计也可以包含诸多问题,所以几乎不可能把这个问题说的清...【详细内容】
2021-12-21  唐少华TSH    Tags:Token   点击:(10)  评论:(0)  加入收藏
实现效果:假如有10条数据,分组展示,默认在当前页面展示4个,点击换一批,从第5个开始继续展示,到最后一组,再重新返回到第一组 data() { return { qList: [], //处理后...【详细内容】
2021-12-17  Mason程    Tags:VUE   点击:(14)  评论:(0)  加入收藏
什么是性能调优?(what) 为什么需要性能调优?(why) 什么时候需要性能调优?(when) 什么地方需要性能调优?(where) 什么时候来进行性能调优?(who) 怎么样进行性能调优?(How) 硬件配...【详细内容】
2021-12-16  软件测试小p    Tags:性能调优   点击:(20)  评论:(0)  加入收藏
Tasker 是一款适用于 Android 设备的高级自动化应用,它可以通过脚本让重复性的操作自动运行,提高效率。 不知道从哪里听说的抖音 app 会导致 OLED 屏幕烧屏。于是就现学现卖,自...【详细内容】
2021-12-15  ITBang    Tags:抖音防烧屏   点击:(25)  评论:(0)  加入收藏
11 月 23 日,Rust Moderation Team(审核团队)在 GitHub 上发布了辞职公告,即刻生效。根据公告,审核团队集体辞职是为了抗议 Rust 核心团队(Core team)在执行社区行为准则和标准上...【详细内容】
2021-12-15  InfoQ    Tags:Rust   点击:(25)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条