一般在项目中我们逗需要把信息存储在本地的情况,比如权限验证的token、用户信息、埋点计数、客户配置的皮肤信息或语言种类等,我们可以暂存一下避免浏览器不必要的请求和客户多余操作,较少请求从而提高性能以给客户使用带来方便。

那么浏览器存储有哪些方法呢,主要有cookie、localStorage、sessionStorage

cookie属于文档对象模型DOM树根节点document,而 sessionStorage 和 localStorage 属于浏览器对象模型BOM的对象window

其中 sessionStorage 和 localStorage 是 HTML5 Web Storage API 提供的

  • sessionStorage:为每一个给定的源(given origin)维持一个独立的存储区域,该存储区域在页面会话期间可用(即只要浏览器处于打开状态,包括页面重新加载和恢复)
  • localStorage:同样的功能,但是在浏览器关闭,然后重新打开后数据仍然存在。

一、Cookie -会话跟踪技术

1、cookie的存取

document.cookie = "username=zhangsan";
document.cookie = "username=zhangsan; expires=Thu, 18 Dec 2013 12:00:00 GMT; path=/"
console.log(document.cookie);
  1. path

路径,值可以是一个目录,或者是一个路径。

如果cc.com/test/index.html 建立了一个cookie,那么在cc.com/test/目录里的所有页面,以及该目录下面任何子目录里的页面都可以访问这个cookie。因此在cc.com/test/test2/test3 里的任何页面都可以访问cc.com/test/index.html建立的cookie。若cc.com/test/ 若想访问cc.com/test/index.html设置的cookes,需要把cookies的path属性设置成“/”。
在指定路径的时候,凡是来自同一服务器,URL里有相同路径的所有WEB页面都可以共享cookies。

  1. domain

主机名,是指同一个域下的不同主机,例如:www.baidu.com和map.baidu.com就是两个不同的主机名。默认情况下,一个主机中创建的cookie在另一个主机下是不能被访问的,但可以通过domain参数来实现对其的控制:document.cookie = “name=value;domain=.baidu.com”
这样,所有*.baidu.com的主机都可以访问该cookie。

  1. expires

过期时间,当过了到期日期时,浏览器会自动删除该cookie,如果想删除一个cookie,只需要把它过期时间设置成过去的时间即可
比如希望设置过期时间一年:new Date().getTime() + 365 * 24 * 60 * 60 * 1000

如果不设置过期时间,则表示这个cookie生命周期为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了

2、特点

  • 只能使用文本 (如果浏览器可以随意在客户端机器上生成文件,比如身份牌是个定时炸弹,安全问题将会变得非常严重)
  • 单条存储有大小限制 4KB (文件若没有大小限制,比如身份牌的重量是140斤,挂脖子能不能累死?)
  • 数量限制 一般浏览器,限制大概在50条左右,你家的门禁卡里能存的下一部蓝光高清么?
  • 读取有域名限制 不可跨域读取,只能由来自 写入cookie的 同一域名 的网页可进行读取简单的讲就是,谁写的cookie,谁才有权利读取。
    (身份牌是我发你的,当然只有我能读取,你媳妇儿的手机自动连接了邻居老王家的wifi,你知道这意味着什么吗?)
  • 时效限制 每个cookie都有时效,最短的有效期是,会话级别:就是当浏览器关闭,那么cookie立即销毁 。(安全学基本理论:密码锁每次打开都需要重新输入密码,输入一次密码,以后就不再验证,就没有安全可言 )

3.优缺点

1.IE6或更低版本最多20个cookie
2.IE7和之后的版本最后可以有50个cookie。
3.Firefox最多50个cookie
4.chrome和Safari没有做硬性限制

Opera 会清理近期最少使用的Firefox会随机清理 4096字节,为了兼容性,一般不能超过 IE 提供了一种存储可以持久化用户数据,叫做IE5.0就开始支持。每个数据最多128K,每个域名下最多1M。这个持久化数据放在缓存中,如果缓存没有清理,那么会一直存在。

优点:极高的扩展性和可用性
1.通过良好的编程,控制保存在cookie中的session对象的大小。
2.通过加密和安全传输技术(SSL),减少cookie被破解的可能性。
3.只在cookie中存放不敏感数据,即使被盗也不会有重大损失。
4.控制cookie的生命期,使之不会永远有效。偷盗者很可能拿到一个过期的cookie。

缺点:

1.Cookie数量和长度的限制。每个domain最多只能有20条cookie,每个cookie长度不能超过4KB,否则会被截掉。
2.安全性问题。如果cookie被人拦截了,那人就可以取得所有的session信息。即使加密也与事无补,因为拦截者并不需要知道cookie的意义,他只要原样转发cookie就可以达到目的了。
3.有些状态不可能保存在客户端。例如,为了防止重复提交表单,我们需要在服务器端保存一个计数器。如果我们把这个计数器保存在客户端,那么它起不到任何作用。

4、插件

Vue
名称:js-Cookie
npm: npm install js-cookie --save
地址:https://www.npmjs.com/package/js-cookie

React
名称:react-cookies
npm:npm install react-cookies --save
地址: https://www.npmjs.com/package/react-cookies

二、localStorage

以键值对(Key-Value)的方式存储,永久存储,永不失效,除非手动删除。IE8+支持,每个域名限制5M。

1、存取

window.localStorage.username = 'hehe'                   // 设置
window.localStorage.setItem('username', 'hehe')         // 设置
window.localStorage.getItem('username')                 // 读取
window.localStorage.removeItem('username')             // 删除
window.localStorage.key(1)                             // 读取索引为1的值
window.localStorage.clear()                            // 清除所有

2、localStorage 的优势

1、localStorage 拓展了 cookie 的 4K 限制。
2、localStorage 会可以将第一次请求的数据直接存储到本地,这个相当于一个 5M 大小的针对于前端页面的数据库,相比于 cookie 可以节约带宽,但是这个却是只有在高版本的浏览器中才支持的。

3、localStorage 的局限

1、浏览器的大小不统一,并且在 IE8 以上的 IE 版本才支持 localStorage 这个属性。
2、目前所有的浏览器中都会把localStorage的值类型限定为string类型,这个在对我们日常比较常见的JSON对象类型需要一些转换。
3、localStorage在浏览器的隐私模式下面是不可读取的。
4、localStorage本质上是对字符串的读取,如果存储内容多的话会消耗内存空间,会导致页面变卡。
5、localStorage不能被爬虫抓取到。
localStorage 与 sessionStorage 的唯一一点区别就是 localStorage 属于永久性存储,而 sessionStorage 属于当会话结束的时候,sessionStorage 中的键值对会被清空。

4、localStorage 使用前

首先在使用 localStorage 的时候,我们需要判断浏览器是否支持 localStorage 这个属性:

if(! window.localStorage){alert("浏览器不支持localstorage");return false;
}else{//主逻辑业务
}

写法

if(!window.localStorage){alert("浏览器不支持localstorage");return false;
}else{var storage=window.localStorage;//写入a字段storage["a"]=1;//写入b字段storage.b=1;//写入c字段storage.setItem("c",3);console.log(typeof storage["a"]);console.log(typeof storage["b"]);console.log(typeof storage["c"]);
}

5、localStorage 键的获取

使用 key() 方法,向其中出入索引即可获取对应的键。

var storage = window.localStorage;
storage.a = 1;
storage.setItem("c",3);for (var i=0;i<storage.length;i++) {var key = storage.key(i);console.log(key);
}

6、localStorage 其他注意事项

一般我们会将 JSON 存入 localStorage 中,但是在 localStorage 会自动将 localStorage 转换成为字符串形式

这个时候我们可以使用 JSON.stringify() 这个方法,来将 JSON 转换成为 JSON 字符串。

if (!window.localStorage) {alert("浏览器不支持localstorage");
} else {var storage = window.localStorage;var data = {name:'xiecanyong',sex:'man',hobby:'program'};var d = JSON.stringify(data);storage.setItem("data",d);console.log(storage.data);
}

读取之后要将 JSON 字符串转换成为 JSON 对象,使用JSON.parse()方法:

var storage = window.localStorage;
var data = {name:'xiecanyong',sex:'man',hobby:'program'
};
var d = JSON.stringify(data);
storage.setItem("data",d);//将JSON字符串转换成为JSON对象输出
var json = storage.getItem("data");
var jsonObj = JSON.parse(json);
// 打印出来是 Object 对象
console.log(typeof jsonObj);

三、sessionStorage

sessionStorage操作的方法与localStroage是一样的,区别在于 sessionStorage 在关闭页面后即被清空,而 localStorage 则会一直保存。很多时候数据只需要在用户浏览一组页面期间使用,关闭窗口后数据就可以丢弃了,这种情况使用sessionStorage就比较方便。

注意,刷新页面sessionStorage不会清除,但是打开同域新页面访问不到。

存取

window.sessionStorage.username = 'hehe'                   // 设置
window.sessionStorage.setItem('username', 'hehe')         // 设置
window.sessionStorage.getItem('username')                 // 读取
window.sessionStorage.removeItem('username')             // 删除
window.sessionStorage.key(1)                             // 读取索引为1的值
window.sessionStorage.clear()                            // 清除所有

四、web storage和cookie的区别

cookie相似,区别是它是为了更大容量存储设计的。Cookie都会被发送过去,这样无形中浪费了带宽,另外 除此之外,setItem ,getItem,removeItem,clear等方法,不像setCookiegetCookie
但是Cookie的作用是与服务器进行交互,作为Web Storage仅仅是为了在本地“存储”数据而生
浏览器的支持除了UserData其实就是web storage。
sessionStorage都具有相同的操作方法,例如removeItem等。

五、IndexedDB

IndexedDB 就是浏览器提供的本地数据库,它可以被网页脚本创建和操作。IndexedDB 允许储存大量数据,提供查找接口,还能建立索引。这些都是 LocalStorage 所不具备的。就数据库类型而言,IndexedDB 不属于关系型数据库(不支持 SQL 查询语句),更接近 NoSQL 数据库。

1、特点

IndexedDB 具有以下特点。

  • 键值对储存。 IndexedDB 内部采用对象仓库(object store)存放数据。所有类型的数据都可以直接存入,包括 JavaScript 对象。对象仓库中,数据以"键值对"的形式保存,每一个数据记录都有对应的主键,主键是独一无二的,不能有重复,否则会抛出一个错误。

  • 异步。 IndexedDB 操作时不会锁死浏览器,用户依然可以进行其他操作,这与 LocalStorage 形成对比,后者的操作是同步的。异步设计是为了防止大量数据的读写,拖慢网页的表现。

  • 支持事务。 IndexedDB 支持事务(transaction),这意味着一系列操作步骤之中,只要有一步失败,整个事务就都取消,数据库回滚到事务发生之前的状态,不存在只改写一部分数据的情况。

  • 同源限制。 IndexedDB 受到同源限制,每一个数据库对应创建它的域名。网页只能访问自身域名下的数据库,而不能访问跨域的数据库。

  • 储存空间大。 IndexedDB 的储存空间比 LocalStorage 大得多,一般来说不少于 250MB,甚至没有上限。

  • 支持二进制储存。 IndexedDB 不仅可以储存字符串,还可以储存二进制数据(ArrayBuffer 对象和 Blob 对象)。

2、概念

IndexedDB 是一个比较复杂的 API,涉及不少概念。它把不同的实体,抽象成一个个对象接口。学习这个 API,就是学习它的各种对象接口。

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

下面是一些主要的概念。

(1)数据库

数据库是一系列相关数据的容器。每个域名(严格的说,是协议 + 域名 + 端口)都可以新建任意多个数据库。

IndexedDB 数据库有版本的概念。同一个时刻,只能有一个版本的数据库存在。如果要修改数据库结构(新增或删除表、索引或者主键),只能通过升级数据库版本完成。

(2)对象仓库

每个数据库包含若干个对象仓库(object store)。它类似于关系型数据库的表格。

(3)数据记录

对象仓库保存的是数据记录。每条记录类似于关系型数据库的行,但是只有主键和数据体两部分。主键用来建立默认的索引,必须是不同的,否则会报错。主键可以是数据记录里面的一个属性,也可以指定为一个递增的整数编号。

{ id: 1, text: 'foo' }

上面的对象中,id属性可以当作主键。

数据体可以是任意数据类型,不限于对象。

(4)索引

为了加速数据的检索,可以在对象仓库里面,为不同的属性建立索引。

(5)事务

数据记录的读写和删改,都要通过事务完成。事务对象提供error、abort和complete三个事件,用来监听操作结果。

3、操作流程

IndexedDB 数据库的各种操作,一般是按照下面的流程进行的。这个部分只给出简单的代码示例,用于快速上手,详细的各个对象的 API 请看这里。

3.1 打开数据库
使用 IndexedDB 的第一步是打开数据库,使用indexedDB.open()方法。

// indexedDB.open('name', 'version')
// 返回一个 IDBRequest 对象
var request = window.indexedDB.open(databaseName, version);

这个方法接受两个参数,第一个参数是字符串,表示数据库的名字。如果指定的数据库不存在,就会新建数据库。第二个参数是整数,表示数据库的版本。如果省略,打开已有数据库时,默认为当前版本;新建数据库时,默认为1。

indexedDB.open()方法返回一个 IDBRequest 对象。这个对象通过三种事件errorsuccessupgradeneeded,处理打开数据库的操作结果。

(1)error 事件

error事件表示打开数据库失败。

request.onerror = function (event) {console.log('数据库打开报错');
};

(2)success 事件

success事件表示成功打开数据库。

var db;request.onsuccess = function (event) {db = request.result;console.log('数据库打开成功');
};

这时,通过request对象的result属性拿到数据库对象。

(3)upgradeneeded 事件

如果指定的版本号,大于数据库的实际版本号,就会发生数据库升级事件upgradeneeded。

var db;request.onupgradeneeded = function (event) {db = event.target.result;
}

这时通过事件对象的target.result属性,拿到数据库实例。

3.2 新建数据库

新建数据库与打开数据库是同一个操作。如果指定的数据库不存在,就会新建。不同之处在于,后续的操作主要在upgradeneeded事件的监听函数里面完成,因为这时版本从无到有,所以会触发这个事件。

通常,新建数据库以后,第一件事是新建对象仓库(即新建表)。

request.onupgradeneeded = function(event) {db = event.target.result;var objectStore = db.createObjectStore('person', { keyPath: 'id' });
}

上面代码中,数据库新建成功以后,新增一张叫做person的表格,主键是id。

更好的写法是先判断一下,这张表格是否存在,如果不存在再新建。

request.onupgradeneeded = function (event) {db = event.target.result;var objectStore;if (!db.objectStoreNames.contains('person')) {objectStore = db.createObjectStore('person', { keyPath: 'id' });}
}

主键(key)是默认建立索引的属性。比如,数据记录是 { id: 1, name: ‘张三’ },那么 id 属性可以作为主键。主键也可以指定为下一层对象的属性,比如 { foo: { bar: ‘baz’ } } 的 foo.bar 也可以指定为主键。

如果数据记录里面没有合适作为主键的属性,那么可以让 IndexedDB 自动生成主键。

var objectStore = db.createObjectStore('person',{ autoIncrement: true }
);

上面代码中,指定主键为一个递增的整数。

新建对象仓库以后,下一步可以新建索引。

request.onupgradeneeded = function(event) {db = event.target.result;var objectStore = db.createObjectStore('person', { keyPath: 'id' });objectStore.createIndex('name', 'name', { unique: false });objectStore.createIndex('email', 'email', { unique: true });
}

上面代码中,IDBObject.createIndex()的三个参数分别为索引名称索引所在的属性配置对象(说明该属性是否包含重复的值)。

3.3 新增数据
新增数据指的是向对象仓库写入数据记录。这需要通过事务完成。

function add() {var request = db.transaction(['person'], 'readwrite').objectStore('person').add({ id: 1, name: '张三', age: 24, email: 'zhangsan@example.com' });request.onsuccess = function (event) {console.log('数据写入成功');};request.onerror = function (event) {console.log('数据写入失败');}
}add();

上面代码中,写入数据需要新建一个事务。新建时必须指定表格名称和操作模式(“只读"或"读写”)。新建事务以后,通过IDBTransaction.objectStore(name)方法,拿到 IDBObjectStore 对象,再通过表格对象的add()方法,向表格写入一条记录。

写入操作是一个异步操作,通过监听连接对象的success事件和error事件,了解是否写入成功。

3.4 读取数据
读取数据也是通过事务完成。

function read() {var transaction = db.transaction(['person']);var objectStore = transaction.objectStore('person');var request = objectStore.get(1);request.onerror = function(event) {console.log('事务失败');};request.onsuccess = function( event) {if (request.result) {console.log('Name: ' + request.result.name);console.log('Age: ' + request.result.age);console.log('Email: ' + request.result.email);} else {console.log('未获得数据记录');}};
}read();

上面代码中,objectStore.get()方法用于读取数据,参数是主键的值。

3.5 遍历数据
遍历数据表格的所有记录,要使用指针对象 IDBCursor。

function readAll() {var objectStore = db.transaction('person').objectStore('person');objectStore.openCursor().onsuccess = function (event) {var cursor = event.target.result;if (cursor) {console.log('Id: ' + cursor.key);console.log('Name: ' + cursor.value.name);console.log('Age: ' + cursor.value.age);console.log('Email: ' + cursor.value.email);cursor.continue();} else {console.log('没有更多数据了!');}};
}readAll();

上面代码中,新建指针对象的openCursor()方法是一个异步操作,所以要监听success事件。

3.6 更新数据
更新数据要使用IDBObject.put()方法。

function update() {var request = db.transaction(['person'], 'readwrite').objectStore('person').put({ id: 1, name: '李四', age: 35, email: 'lisi@example.com' });request.onsuccess = function (event) {console.log('数据更新成功');};request.onerror = function (event) {console.log('数据更新失败');}
}update();

上面代码中,put()方法自动更新了主键为1的记录。

3.7 删除数据
IDBObjectStore.delete()方法用于删除记录。

function remove() {var request = db.transaction(['person'], 'readwrite').objectStore('person').delete(1);request.onsuccess = function (event) {console.log('数据删除成功');};
}remove();

3.8 使用索引
索引的意义在于,可以让你搜索任意字段,也就是说从任意字段拿到数据记录。如果不建立索引,默认只能搜索主键(即从主键取值)。

假定新建表格的时候,对name字段建立了索引。

objectStore.createIndex('name', 'name', { unique: false });
现在,就可以从name找到对应的数据记录了。

var transaction = db.transaction(['person'], 'readonly');
var store = transaction.objectStore('person');
var index = store.index('name');
var request = index.get('李四');request.onsuccess = function (e) {var result = e.target.result;if (result) {// ...} else {// ...}
}

浏览器储存之Cookie、sessionStorage、localStorage和indexedDB区别与详解相关推荐

  1. 浏览器存储,储存,Cookie,WebStorage,IndexedDB

    前言: Cookie存储数据的功能已经很难满足开发所需,逐渐被WebStorage.IndexedDB所取代: 一.Cookie 什么是Cookie及应用场景 Cookie指网站为了储存一些信息,辨别 ...

  2. 浏览器本地存储Cookie、LocalStorage、SessionStorage

    文章目录 浏览器本地存储 浏览器本地存储 浏览器本地存储方式 (1)Cookie Cookie 是最早被提出来的本地存储方式,在此之前,服务端是无法判断网络中的两个请求是否是同一用户发起的,为解决这个 ...

  3. session,cookie,sessionStorage,localStorage的区别及应用场景

    浏览器的缓存机制提供了可以将用户数据存储在客户端上的方式,可以利用cookie,session等跟服务端进行数据交互. 一.cookie和session cookie和session都是用来跟踪浏览器 ...

  4. 浅谈session,cookie,sessionStorage,localStorage的区别及应用场景

    浏览器的缓存机制提供了可以将用户数据存储在客户端上的方式,可以利用cookie,session等跟服务端进行数据交互. 一.cookie和session cookie和session都是用来跟踪浏览器 ...

  5. 计算机网络-自顶向下-Web应用2(Cookie、Web缓存、条件GET详解)

    Web应用2 计算机网络所有笔记链接 Cookie技术 前面提到HTTP的服务是 无状态的,这简化了服务器的设计,但是Web站点还是很有必要具有能够识别用户的功能的.比如说你至少能够把我密码啥的记录了 ...

  6. html domin属性,cookie中的path与domain属性详解

    1.domain表示的是cookie所在的域,默认为请求的地址,如网址为www.jb51.net/test/test.aspx,那么domain默认为www.jb51.net.而跨域访问,如域A为t1 ...

  7. 用PHP实现浏览器点击下载各种格式文档的方法详解【txt apk等等】

    [[注:其他文件想设置成下载文件,和下面介绍的方法一致]] 由于现在的浏览器已经可以识别txt文档格式,如果只给txt文档做一个文字链接的话,点击后只是打开一个新窗口显示txt文件的内容,并不能实现点 ...

  8. rem适配的浏览器_[史上最全]UI相关尺寸单位详解 | px、pt、dp、sp、rem、vwvh、rpx、ppi、dpi、dppx...

    先给进来看文章的你点个赞 尺寸适配应该由开发同事负责处理,处理不好是他的问题,你有兴趣了解这些让人头疼的事,证明你是共产主义好社畜,还有工作量不饱和,Good for you~适配问题是影响设计复现的 ...

  9. axios库读不到cookie_axios中cookie跨域及相关配置示例详解

    自从入了vue之后,一直在用axios这个库来做一些异步请求,下面这篇文章主要介绍关于axios中cookie跨域及相关配置的资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴. 前言 最近 ...

最新文章

  1. 1012. 数字分类 java_PAT-B-1012. 数字分类(Java)
  2. LeetCode 111. Minimum Depth of Binary Tree--Java, Python解法--二叉树最小高度--迭代,递归
  3. python标准库学习9
  4. python程序员面试宝典 勘误_《前端面试江湖》勘误合集(二)
  5. 黑马lavarel教程---11、响应处理
  6. JAVA报错是一层一层的吗_Java异常处理:给程序罩一层保险
  7. 符号链接文件_Windows10下创建符号链接(SymbolicLink)
  8. mysql 2027_阿里云mysql远程登录报ERROR 2027(HY000)
  9. c# contains方法_C#/.Net Core/WPF框架初建(国际化、主题色)
  10. wms智能仓储系统不可缺少?
  11. 机器学习之工程师入门路线
  12. 怎么阻止acrobat自动更新升级?
  13. 用c语言小游戏代码大全,c语言经典游戏代码
  14. 和平精英微信和qq不是一个服务器,和平精英qq和微信能一起玩吗 qq微信数据互通吗...
  15. 基于node.js的网页聊天系统设计与实现
  16. Vue CLI构建SPA项目教你手把手创建SPA项目
  17. 用python完成选股策略a股_Python 金融: 0亏损选股策略
  18. 怎样找到ant压缩这个软件_PDF压缩到最小该怎么完成?这个PDF压缩软件最实用
  19. 高德地图2016清明出行交通预测报告(完整版)
  20. 潮汕牛肉火锅,美味在你身边

热门文章

  1. 【JavaScript】黑点捉红点并躲绿点游戏
  2. Redis社交应用里面之关注、粉丝、共同好友案例
  3. 木字楠后台管理系统开发(3):Vue项目初始化并引入基础依赖
  4. go语言实现最小区块链教程5-地址
  5. python发微信提醒天气冷了注意保暖_2019天气变冷的朋友圈说说 注意保暖的微信问候语...
  6. Devexpress控件使用皮肤,设置默认皮肤及动态换肤
  7. 华为蓝牙耳机推荐哪款好?佩戴舒适的无线耳机推荐
  8. Stratasys:光固化3d打印机优缺点论点,需品牌品质落实
  9. 【matlab数学建模】运用建立的模型分别为这四组游客设计旅行计划
  10. 披着羊皮的狼?表面看着是个轻薄本,可实际上却是个游戏本