欢迎各位兄弟 发布技术文章
这里的技术是共享的
最近需要整理一下前端浏览器都有哪种存储方式,一共是5种,cookies、local storage、session storage、web sql、indexedDB,本文将分别就大小,有效期,和使用方法等方面进行阐述。
一个域名domain下,单cookie总大小在4KB以内,总条数一般有限。只适合存放身份认证信息。
默认是浏览器关闭就会销毁,也可以通过setMaxAge方法设置Expires/Max-age属性,来决定有效期。
cookie.setMaxAge(60*60) // 存活60*60秒
cookie.setMaxAge(-1) // 浏览器关闭就会销毁,这也是默认值
cookie.setMaxAge(0) // 特殊值0,表示改cookie作废
复制代码
name和value是键值对,也就是常用的部分
domain指的是域名,在该域名下的请求,才会携带此cookie,且对子域名也生效,domain参数以(".")符号点开始。
path指的是cookie的有效路径,同样是会对子路径生效,path参数以("/")符号点结尾。
Expires/Max-age指的是cookie的有效期,expires是cookie失效的时间戳(服务器时间), max-age是几秒后失效,单位为秒,默认为-1。
size指的是大小,各浏览器大小不同,如下表
浏览器 | Cookie最大条数 | Cookie最大长度/单位:字节 |
---|---|---|
IE | 50 | 4095 |
Chrome | 150 | 4096 |
FireFox | 50 | 4097 |
Opera | 30 | 4096 |
Safari | 无限 | 4097 |
httpOnly
true: document.cookie不可见该条cookie,也不可修改,但请求还是会携带。 false: 默认值,可见可修改,请求会携带。
Secure是安全属性,若为true,则只能在https和ssl等安全协议中传输
SameSite是用来限制第三方Cookie,有三个属性值
Strict,最严格,完成禁止第三方Cookie,跨站点时,任何情况下都不会发送Cookie;
Lax是大多数情况不发送第三方Cookie,但get请求会携带;
None,不做限制,但必须Secure是true。
复制代码
Priority优先级,属性值low/medium/high,当cookie数量超出的时候,低优先级的cookie会被清除。
import Cookies from 'js-cookie'
const TokenKey = '键名'
const token = 'token值'
// 存储
Cookies.set(TokenKey, token)
// 获取
Cookies.get(TokenKey)
复制代码
原生的写法
document.cookie="key=value;Max-age=60*60"
// 键值对,";"分号分隔,其余属性也是一样的写法
复制代码
一般为5M左右,只能存储字符串格式的数据,所以存储前需要转换成json串,需要时取出再转换。
默认是永久生效,只有两种清除方式,第一种通过js代码控制(能写入肯定能清除),第二种是使用浏览器的 ‘清除浏览数据’ 功能。
如果有需要可以自行百度,手动实现一个api,去设置local storage的有效期
为了弥补cookie存储大小不足,在h5里新增的一项存储技术Web storage,它分为local storage 和session storage两种,本质上两种不存在区别,唯一区别的是local storage是长期存储,session storage是会话存储(标签页关闭就会清除)。而且请求时,并不会带上web storage存储的值(这点和cookie不一样)。
local storage要求是同协议,同域名,同端口,就能共享或修改同一份localStorage数据。
session storage则要求同协议,同域名,同端口,同窗口(即同个浏览器标签页)
Web storage的api是一致的,除了调用前缀不同而已,下面是local storage的调用方法。
官方api有以下几种:
getItem 获取
setItem 设置
removeItem 移除
clear 清空
localStorage.getItem('key') // 获取键名为key的值
localStorage.setItem('key','value') // 设置键名为key,并赋值,若存在就会
//修改属性值,这里的value必须是字符串,若是对象可以调用JSON.stringify(obj)
//来序列化成字符串
localStorage.removeItem('key') // 移除键名为key的值
localStorage.clear('key') // 清空所有值
当然,因为local storage是数组,所以数组的增删改查也可以对其生效。不过不推荐。
复制代码
一般为5M左右,只能存储字符串格式的数据,所以存储前需要转换成json串,需要时取出再转换。
标签页关闭就会清空
这部分跟local storage一致,参照第三点
无限制
刷新当前页面,or 关闭当前页面失效
Web SQL 数据库 API 并不是 HTML5 规范的一部分,但是它是一个独立的规范,引入了一组使用 SQL 操作客户端数据库的 APIs,相当于是在浏览器中内置了一个sqlite关系型数据库,不过操作是由js去操作sql来实现的。
不过web sql存在兼容性差的限制,只能在最新版的 Safari, Chrome 和 Opera 浏览器中使用,ie和Firefox则均不支持。
核心方法就三个
1. **openDatabase**:这个方法使用现有的数据库或者新建的
数据库创建一个数据库对象。
2. **transaction**:这个方法让我们能够控制一个事务,以及
基于这种情况执行提交或者回滚。
3. **executeSql**:这个方法用于执行实际的 SQL 查询。
复制代码
打开or创建数据库openDatabase
// 数据库名称,版本号,描述文本,容量大小, 回调函数(非必选)
var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024);
复制代码
执行查询transaction,里面去调用executeSql函数,参数的基本语句和mysql的一致。
db.transaction(function (tx) {
tx.executeSql('CREATE TABLE IF NOT EXISTS LOGS (id unique, log)');
});
复制代码
对熟悉后端mysql数据库的码农来说,应该是小菜一碟,这里就不多赘述了,有兴趣的可以自行百度。
无限制,专门用来存放大数据,存储大小一般有50m-250m(受硬盘限制),上不封顶。
会在本机一直保存。以下几种情况会清除。
若是浏览器的无痕模式,那在退出所有无痕窗口后,会清除indexDB;
若是浏览器设置,退出前清除浏览数据,也会清除;
若是在浏览器控制手动删除indexDB数据库,也会清除。
若是在js中调用deleteDatabase方法,也可以清除。
复制代码
indexDB是一款对象型数据库,它会在客户端本地根据网址等创建具体文件数据,indexDB(浏览器数据库)本机存储文件夹在以下路径(以google为例)。
1)windows版本 C:\Users\ ‘当前的登录用户’\AppData\Local\Google\Chrome\User Data\Default\IndexedDB\
2)linux版本 `/home/[当前登录用户]/.config/google-chrome/Default/IndexedDB/`
复制代码
indexDB一共有以下几个特性
a、键值对储存。 主键独一无二
b、异步。 异步操作,防止操作数据库时,拖慢网页。
c、支持事务。 这意味着,如果事务中有一步失败,数据库将回滚到事务发生前的状态。
d、同源限制。 每个数据库是根据域名创建的,网页只能访问自身域名下的数据库,禁止跨域访问。
e、存储空间大。 一般浏览器会分配50m-250m这个值,但也受硬盘大小影响,可以没有上限。
f、支持二进制存储。 这点和web storage不同,意味着不需要额外转成字符串才能进行存储。
g、兼容性。
(1)IE10起支持
(2)Firefox 10、Chrome 23、Opera 15
(3)最新版的桌面版或移动版的Safari也支持IndexedDB。
indexDB的使用分3步
a、打开数据库DB
b、在versionChange事件中 创建表(ObjectStore),包括定义表的键,索引规则等。
c、操作数据(增删改查,都是用事务做)
操作数据分4步
c-1、开启事务
c-2、获取事务中的objectStore
c-3、通过objectStore发起操作请求
c-4、定义请求的回调函数
复制代码
首先是打开数据库
const opendbRequest = indexedDB.open("MyDatabase", version);
复制代码
上述的opendbRequest会有四个状态
sucess 打开成功
error 打开失败
upgradeneeded 首次打开或者数据库版本变化时会触发,先本事件,再是sucess等事件
blocked 上一次连接还没关闭
复制代码
// 注意:并不是直接打开数据库,而是发起了一个打开数据库的请求!这里当verison比现存的db版本大,或者不存在当前db的时候,就会触发一个changeVersion的事件,会触发upgradeneeded回调。
let db;
opendbRequest.onsuccess = function(event) {
// 请求的 success 回调里面就可以获取打开的数据库了:
db = event.target.result; // 或 opendbRequest.result
};
复制代码
打开完数据库,那就是对数据库的各种设置了
opendbRequest.onupgradeneeded = e=>{
const db = e.target.result
// 只有在这个回调里面,才能定义(增删改)对象仓库及对象仓库的规则!
// 术语:对象仓库(objectStore) 相当于 MySQL中的表(table),mogodb中的repository(仓库)
// 创建objectStore
// 创建时 一定要注意定义好key的规范,key就相当于
// MySQL里的主键,关于key的规范请百度查询
const objectStore = DB.createObjectStore('myObjectStore', { keyPath: 'id' });
// 创建索引:
// 有联合索引,唯一索引,对数组字段建索引
objectStore.createIndex('index_name', ['field1', 'field2', 'field3'], { unique: true })\
}
复制代码
设置完,才可以用事务,对数据库里的数据进行增删查改
// 创建事务:
// 第一个参数指明事务所涉及的objectStores,如果只有一个objectStore,[]可以省略,本例可以直接写 'myObjectStore'
// 第二参数指明事务操作数据的方式,如不写 默认是 readonly,表示只能读数据 不能写。如果不仅仅是读,还有增删改数据,必须用 readwrite。
// 请注意 readwrite 事务性能较低,并且只能有一个处于活动状态。所以除非必要,不要随意使用readwrite!
let transaction = db.transaction(['myObjectStore'],'readwrite')
// 获取事务中的objectStore (**注意:** objectStore只有事务才能获取,而不能通过db直接获取)
let objectStore = transaction.objectStore('myObjectStore')
// 在事务objectStore上发起操作数据的请求:(注意只有objectStore才能发起操作数据的请求!)
// add 新增, put 不存在相同key值的,是新增;存在,是修改,
// delete 删除,get 查询 这两个参数只能传入特定对象的 key!如:let request = objectStore.delete(myKey)
let request = objectStore.add(modifyData)
// 请求成功的回调
request.onsuccess = e => {
console.log('添加数据成功。新数据的key是:',e.target.result)
}
复制代码
如果不需要了,要删除数据库
var DBDeleteRequest = window.indexedDB.deleteDatabase('MyDatabase');
// 成功
DBDeleteRequest.onerror = function () {};
// 失败
DBDeleteRequest.onsuccess = function () {};
复制代码
本文对于indexDB的阐述不够详细,感兴趣的可以去文档里继续查看。 IndexedDB - Web API 接口参考 | MDN
也可以了解一下dexie.js, 这是对indexDB封装过的,用起来比原生的indexDB简便一些。
5、使用场景
threejs的3d模型,一般都较大,可以异步请求,先存储到本地
indexDB数据库,需要时再本地读取,速度比从服务端请求快得多。
地图基础数据,特别是路段基础数据,动辄上w条数据,基本也
得有10几m,甚至更多,也可以首次请求完存储到本地indexDB数据库。
图片的大批量提交,blob数据也可以暂存于indexDB,避免重复
获取,生产多余垃圾。
离线应用,在有网络的情况下,保存服务端数据,以便离线时,
应用能够正常使用。
页面间共用的大数据,或者结构特别复杂的数据,此时可以选择
用indexDB管理会简单些。
复制代码
ps: 整理不易,点个赞吧
来自 https://www.cnblogs.com/Earth-Hall-Sanwu/p/16673008.html