JS-前端数据存储

客户端存储是快速为一个应用进行性能优化的绝佳方法。通过把数据存储在浏览器中,用户不必每次都向服务器请求获取同一个信息。在你离线时,使用本地存储的数据而不是向远端服务器上请求数据就显得非常有用,甚至在线用户也可以从中获益。 客户端存储可以通过这些技术来实现:cookie、sessionstorage、Local Storage (更准确地说是“Web Storage”)、IndexedDB、userData。

一、cookie

1、cookie的作用  

  说到cookie,其实cookie有两个主要功能,第一个功能就是用于解决http无状态的缺点,在客户端存储会话信息,记录用户的状态,而第二个功能也就是我们现在也经常使用cookie在客户端存储一些其它的数据

2、cookie的构成

  一般来说,cookie是由浏览器保存的以下几块信息构成的

  (1)名称:一个唯一确定cookie的名称

  (2)值:存储在cookie中的字符串值,值必须被URL编码

  (3)域:cookie对于哪个域是有效的,所有向该域发送的请求都会包含这个cookie信息

  (4)路径:对于指定域中的路径,应该向服务器发送cookie

  (5)失效时间:表示cookie何时应该被删除的时间戳

  (6)安全标志:指定后,cookie只有在使用SSL连接的时候才发送到服务器

 

3、如何使用cookie存储数据

  一般来说,有两种方式可以生成cookie,一种是服务器发送http响应时指定Set-Cookie进行指定,另一种我们可以使用js生成cookie

  由于cookie需要通过URL编码,因此在写入cookie时和读取cookie时我们都需要进行编码和解码操作,为了方便,我们可以自己写一个cookie的操作对象

复制代码
var CookieUtil = {
    get: function(name) {
        var cookieName = encodeURIComponent(name) + "=",
              cookieStart = document.cookie.indexOf(cookieName),
              cookieValue = null;
         
         if(cookieStart > -1) {
             var cookieEnd = document.cookie.indexOf(";", cookieStart);
             if (cookieEnd == -1) {
               cookieEnd = document.cookie.length;
             }
             cookieValue = decodeURIComponent(document.cookie.substring(cookieStart + cookieName.length, cookieEnd));
         }
         return cookieValue;
    },
    set: function(name, value, expires, path, domain, secure) {
        var cookieText = encodeURIComponent(name) + "=" + encodeURIComponent(valeu);
        if(expires instanceof Data) {
            cookieText += ";expires=" + expires.toGMTString();
        }
        if(path) {
            cookieText += ";path=" + path;
        }
        if(domain) {
            cookieText += ";domain=" + domain;
        }
        if(secure) {
            cookieText += ";secure";
        }
        document.cookie = cookieText;
    }
    unset: function(name, path, domain, secure) {
        this.set(name, "", new Date(0), path, domain, secure);
    }
}
复制代码

  当我们想在cookie存储一些数据,比如存储用户是否点击广告的状态,可以像下面这样设置

CookieUtil.set("ifClick", "true");

  当我们想判断用户是否点击了广告时,就需要从cookie拿出数据,可以像下面这样获取数据

CookieUtil.get("ifClick");

  通过从cookie中获取出我们存入的ifClick数据,我们可以得到相应的值为true,好啦,这个广告用户已经点击了,不用显示小红点啦

 

4、cookie的缺点

  虽然cookie可以存储一些数据,但是仍然存储下面一些缺点

  (1)cookie需要在客户端和服务器端之间来回传送,会浪费不必要的资源

  (2)cookie的存储大小有限制,对于每个域,一般只能设置20个cookie,每个cookie大小不能超过4KB

  (3)cookie的安全性,cookie因为保存在客户端中,其中包含的任何数据都可以被他人访问,cookie安全性比较低

 

二、Web存储机制

接下来,我们要说一下html5中的存储啦,主要是sessionStorage和localStrorage

1、什么是Web存储

  Web Storage也是一种在客户端存储数据的一种机制,主要的目的是为了克服由cookie带来的一些限制,当数据需要被严格控制在客户端上时,无须将数据在客户端和服务器之间来回的进行传送,并且可以存储大量的跨会话的数据

  一般来说,Web Storage包含了两种对象的定义,sessionStorage和globalStorage,而现在localStorage在修订过的html5规范中作为持久保存客户端数据的方案取代了globalStorage,接下来,让我们看一下它们有什么区别啦

 

2、sessionStorage

(1)什么是sessionStorage

  sessionStorage对象是存储特定于某个会话的数据,也就是数据只保存到浏览器关闭,这个对象就像会话cookie,也会在浏览器关闭后消失,存储在sessionStorage中的数据可以跨越页面刷新而存在

(2)如何使用sessionStorage存储数据

  由于sessionStorage对象是Storage的一个实例,所以存储数据时可以使用setItem()或者直接设置新的属性来存储数据

//  使用方法存储数据
sessionStorage.setItem("ifClick", "true");

//  使用属性存储数据
sessionStorage.ifClick = "true";

  当我们要获取某个数据的时候,可以使用getItem来获取数据

sessionStorage.getItem("ifClick");

  我们现在又成功获取到ifClick的值啦,当然也可以通过length属性和key()方法来获取sessionStorage的值

(3)sessionStorage的特点

  a、同源策略限制,若想在不同页面之间对同一个sessionStorage进行操作,这些页面必须在同一协议、同一主机名和同一端口下

  b、单标签页限制,sessionStorage操作限制在单个标签页中,在此标签页进行同源页面访问都可以共享sessionStorage数据

  c、只在本地存储,seesionStorage的数据不会跟随HTTP请求一起发送到服务器,只会在本地生效,并在关闭标签页后清除数据

  d、存储方式,seesionStorage的存储方式采用key、value的方式

  e、存储上限限制:不同的浏览器存储的上限也不一样,但大多数浏览器把上限限制在5MB以下

 

3、globalStorage

(1)什么是globalStorage

  作为最初的Web Storage的一部分,这个对象的目的是跨越会话存储数据,但有特定的访问限制,现在globalStorage已经被localStorage取代

(2)如何使用globalStorage存储数据

  要使用globalStorage,首先要指定哪些域可以访问该数据,可以通过方括号标记使用属性来实现

globalStorage["aaa.com"].ifClick = "true";

  在上面的代码中,访问的是针对域名aaa.com的存储空间,这个存储空间对于aaa.com及其所有子域都是可以访问的,我们可以像下面这样来获取数据

globalStorage[aaa.com].getItem("ifClick");

  因为globalStorage现在已经比较少使用,如果大家想使用,还是使用localStorage

(3)globalStorage的特点

  如果不使用removeItem()或者delete删除,或者用户未清除浏览器缓存,数据将会一直保存在磁盘上,因此很适合在客户端存储文档或者长期保存用户偏好设置

 

4、localStorage

(1)什么是localStorage

  localStorage对象在修订过的html5规范中作为持久保存客户端数据的方案却带了globalStorage,与globalStorage不同,不能给localStorage指定任何访问规则,因为规则已经事先订好了,要访问同一个localStorage对象,页面必须来自同一个域名,使用同一种协议,在同一个端口

(2)如何使用localStorage存储数据

  由于localStorage是Storage的实例,可以像使用sessionStorage一样来使用它

localStorage.setItem("ifClick","true");

  当我们要获取数据的时候,可以像下面这样获取

localStorage.getItem("ifClick");

  存储在localStorage中的数据和存储在globalStorage中的数据一样,都遵循相同的规则,数据保留到通过js删除或者是用户清除浏览器缓存

(3)localStorage的特点

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

  b、目前所有的浏览器中都会把localStorage的值类型限定为string类型,这个在对我们日常比较常见的JSON对象类型需要一些转换

  c、localStorage本质上是对字符串的读取,如果存储内容多的话会消耗内存空间,会导致页面变卡

  最后,要和大家说的是,sessionStorage和localStorage都克服了cookie的一些限制,它们都有很多共同的特点,localStorage与sessionStorage的唯一一点区别就是localStorage属于永久性存储,而sessionStorage属于当会话结束的时候,sessionStorage中的键值对会被清空。

 ps:【每个浏览器对localstorage的支持大小是不一样的,chrome是5M ,IE10是1630K。 可以用下面的js匿名函数测试不同浏览器对localstorage的支持大小】

(function() {
if(!window.localStorage) {
console.log('当前浏览器不支持localStorage!')
}
var test = '0123456789';
var add = function(num) {
num += num;
if(num.length == 10240) {
test = num;
return;
}
add(num);
}
add(test);
var sum = test;
var show = setInterval(function(){
sum += test;
try {
window.localStorage.removeItem('test');
window.localStorage.setItem('test', sum);
console.log(sum.length / 1024 + 'KB');
} catch(e) {
alert(sum.length / 1024 + 'KB超出最大限制');
clearInterval(show);
}
}, 0.1)
})()

 

三、IndexedDB

1、为什么会有IndexedDB

  现有的浏览器数据储存方案,都不适合储存大量数据:Cookie 的大小不超过4KB,且每次请求都会发送回服务器;LocalStorage 在 2.5MB 到 10MB 之间(各家浏览器不同),而且不提供搜索功能,不能建立自定义的索引,所以,需要一种新的解决方案,这就是 IndexedDB 诞生的背景

 

2、什么是IndexedDB

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

 

3、IndexedDB的特点

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

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

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

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

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

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

  

四、IE用户数据

虽然H5中可以通过localstorage和sessionstorage进行数据存储,但是低版本的ie不支持呀,这可怎么办?为了在ie中存储数据,微软通过一个自定义行为引入了持久化用户数据的概念

1、什么是userData

  userData是ie的一种数据存储方式,userData 存储通过将数据写入一个UserData存储区(UserData store)来保存数据,userData将数据以XML格式保存在客户端上,UserData存储方式只适用于IE浏览器,UserData存储区保存以后,即使IE浏览器关闭或者刷新了,下一次进入该页面,数据也能够重新载入而不会丢失,也就是数据将一直存在,除 非你人为删除或者用脚本设置了该数据的失效期

  一般来说,userData允许每个文档最多保存128KB数据,每个域名最多1MB数据,是不是会比cookie存储的数据要大呢?

 

2、如何使用userData存储数据

  如果我们想使用userData存储数据,首先必须使用css在某个元素上指定userData行为

<div style="behavior:url(#default#userData)" id="dataStore></div>

  一旦该元素使用了userData行为,那么就可以使用setAttribute()方法在上面保存数据了,为了将数据提交到浏览器缓存中,还必须调用save()方法并告诉它要保存到的数据空间的名字,数据空间名字可以完全任意,仅用于区分不同的数据集

var dataStore = document.getElementById("dataStore");
dataStore.setAttribute("ifClick", "true");
dataStore.save("ClickInfo");

  在上面的代码中,在使用setAttribute存储了数据之后,调用了save方法,指定了数据空间的名称ClickInfo,下一次页面载入后,可以使用load方法指定同样的数据空间来获取数据

dataStore.load("ClickInfo");
dataStore.getAttribute("ifClick");

  在上面的代码中,对load()的调用获取了ClickInfo数据空间里的所有信息,并且使数据可以通过元素访问,只有到载入确切完成之后数据才可以使用,好啦,现在我们又成功获取到了ifClick的值啦,ifClick的值为true,好啦,广告已经点击,不显示小红点

  如果getAttribute()调用了不存在的名称或者是尚未载入的名称,则返回null,我们也可以使用removeAttribute()方法来删除某个数据

dataStore.removeAttribute("ifClick");

 

3、userData的缺点

  (1)userData只是针对ie的数据存储

  (2)userData的访问限制和对cookie的访问限制一样,必须来自同一个域名,在同一个路径下,并使用与进行存储脚本同样的协议才能访问

  (3)userData的数据也是不安全的,不能存放重要的信息

 

------------------------------------------------------------------------------------------------------------

原文链接:https://www.cnblogs.com/Yellow-ice/p/10507472.html

 

 

 =============================================================分割线====================================================================================================

localStorage单页面及不同页面监听变动

1.单页面监听storage事件

var orignalSetItem = localStorage.setItem;
localStorage.setItem = function(key,newValue){
var setItemEvent = new Event("setItemEvent");
setItemEvent.key=key;
setItemEvent.newValue = newValue;
window.dispatchEvent(setItemEvent);
orignalSetItem.apply(this,arguments);
}


window.addEventListener("setItemEvent", function(e) {
              
console.log(e.key+"~~~"+e.newValue)
  
});

2.不同页面

1)监听了storage事件

<!DOCTYPE html>
<html>
<head lang="en">
<title>A</title>
</head>
<body>
<script>
window.addEventListener("storage", function (e) {
alert(e.newValue);
});
</script>
</body>
</html>

 

2)修改了localStorage

<!DOCTYPE html>
<html>
<head lang="en">
<title>B</title>
</head>
<body>
<script>
localStorage.clear();
localStorage.setItem('foo', 'bar');
</script>
</body>
</html>
————————————————
原文链接:https://blog.csdn.net/qq_42076140/article/details/80307326

 

-------------------------------------------VUE------------------------------

 

vue-重写localStorage.setItem方法以监听变动,实时更新

解决本地存储的值改变的时候js不能实时监听到的问题
问题描述:我们在js里面获取了某一个localstorage的值,但是后期它可能改变了,我们js只执行一遍没办法再次获取它的值,当然可以刷新页面获取,但如果是我们的但页面就不能刷新页面了,此时:
我们可以重写localStorage的setItem方法,当调用setItem方法设置新值的时候,会new Event('setItemEvent')
但是只是实例化事件了,怎么去监听呢?
我们可以用window.dispatchEvent()这个方法来派发一个事件,让window去监听。新实例出来的这个事件会被绑定到window上来监听它的调用,当调用的时候可以拿到setItem的新值,直接赋值就可以
具体实现
先在src下新建utils文件夹,新建tools.js,它会抛出一个dispatchEventStroage方法
// 重写setItem事件,当使用setItem的时候,触发,window.dispatchEvent派发事件
dispatchEventStroage () {
const signSetItem = localStorage.setItem
localStorage.setItem = function (key, val) {
let setEvent = new Event('setItemEvent')
setEvent.key = key
setEvent.newValue = val
window.dispatchEvent(setEvent)
signSetItem.apply(this, arguments)
}
}
在main.js里面全局引入,并use,然后调用该dispatchEventStroage方法,以解决setitemEvent不会立即生效的问题
import Tools from '@/utils/tools'
Vue.use(Tools)
// 为了解决setItemEvent不立即生效,使用事件派发强制更高
Tools.dispatchEventStroage()
 

然后就可以使用了
如果我们在每次发送请求的时候都需要携带token字段,token有时候可以存在localstorage里面,但是当token发生改变时,我们js不知道已经改变,所以就需要用到以上方法了。
const reqHeaders = {
Accept: 'text/json',
// 第一次登录之后返回的token,之后每次请求都携带token字段进行验证
token: localStorage.getItem('token') || ''
}
// window全局监听localStorage的setItem事件以及时更新
window.addEventListener('setItemEvent', function (e) {
reqHeaders.token = e.newValue
})
 
————————————————
原文链接:https://blog.csdn.net/weixin_43869192/article/details/85061248

 

转载于:https://www.cnblogs.com/sylvia-Camellia/p/11589569.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值