关于H5存储,你到底知道多少呢?
近几年,前端快速发展,令人诧异,抛开几乎一年一更的vue框架,作为前端代表的HTML也早就迎来了更新——W3C发布HTML5作为新的浏览器网站规范,其中最令人激动的莫过于各种API的使用和Web Storage(即:页面存储)以及页面SQL的支持了。
Web Storage
1.sessionStorage存储
完全适应了JavaWeb中session会话的方式,将数据保存在客户端本地,session对象中。
何为session?
用户在浏览某个网站时,从进入网站到浏览器关闭所经过的时间,也就是用户浏览这个网站所花费的时间。
Session对象可以用来保存这段时间内所要求保存的任何数据,如图 Web - Storage :
可以看到,webStorage API的操作机制实际上是对键值对的操作。
session数据的存储和获取:
在sessionStorage中设置键值对数据可以用setItem(),代码如下:sessionStorage.setItem("key","value");
获取数据可以应用getItem(),代码如下:var val=sessionStorage.getItem("key");
当然也可以直接用sessionStorage的key方法,而不是用setItem和getItem方法,代码如下:sessionStorage.key="value"; var val=sessionStorage.key;
要知道,HTML5存储是基于键值对(key/value)的形式存储的,每个键值对称为一个项(item)。
存储和检索数据都是通过指定的键名,键名的类型是字符串类型。值可以是包括字符串、布尔值、整数。或者浮点数在内的任意JavaScript支持的类型,但是,最终数据是以字符串类型存储的。
调用结果是将字符串value设置到sessionStorage中,这些数据随后可以通过键key获取。调用setItem()时,如果指定的键名已经存在,那么新传入的数据会覆盖原先的数据。调用getItem时,如果传入的键名不存在,那么会返回null,而不会抛出异常。
说明: 在保存数据时,如果使用sessionStorage读取或存储数据,则需要使用sessionStorage对象并调用该对象的读写方法;如果使用localStorage读写或保存数据,则需要使用localStorage对象并调用该对象的读写方法。
sessionStorage中,数据仅能在同一个会话内得以保留:
共享sessionStorage的情况::
通常的页面跳转时;在iframe内打开了子页面;从崩溃中恢复时;重新加载(刷新)时
sessionStorage不能共享(返回时保存状态消失)的情况:
在新窗口或新标签页中打开了页面;窗口关闭后又被重新打开
2.localStorage存储
相比于sessionStorage,我觉得在大部分情况下(如:登录注册),还是用localStorage更方便一些。
localStorage将数据保存在客户端本地的硬件设备中,即使浏览器被关闭了,该数据仍然存在,下次打开浏览器访问该网站时仍然可以继续使用。
下面介绍一下如何删除和清空localStorage中保存的数据:
(1)removeItem()方法
removeItem()方法用于从Storage列表删除数据,如:var val=localStorage.removeItem(key);
也可以通过传入数据项的key从而删除对应的存储数据,如:var val=localStorage.removeItem(1);
(说明:数字1会被转换为string,因为key的类型就是字符串。)
(2)clear()方法
clear()方法用于清空整个列表的所有数据,如:localStorage.clear();
同属可以通过使用length属性获取Storage中存储的键值对个数。
var val=localStorage.length;
注意: removeItem可以清除给定的key所对应的项,如果key不存在,则“什么也不做”;clear会清除所有的项,如果列表本来就是空的,就“什么也不做”。
如我在南阳理工学院-优C社团官网中所使用的localStorage技术实现“登陆功能”
(也可以通过此处:优C工作室-南阳理工学院进入)(电脑打开效果为佳!电脑打开!)
我在一个页面设置登录和密码保存,以及验证(通过HTML5和vue(前端框架))
核心代码(14-21、24-31行):
<script>
function $$(id) {
return document.getElementById(id);
}
function pageload() {
//下面 if-else语句的含义是:判断用户是否是第一次登录此界面,通过这个判断按钮的显示值——这是通过cookie实现的
if (document.cookie.indexOf("user=new") === -1) {
document.getElementById("deng1").value="注册";
var t = new Date(new Date().getTime() + 1000 * 60 * 60 * 24 * 30);
document.cookie = "user=new; expires=" + t.toGMTString();
}else{
document.getElementById("deng1").value="登录";
}
var strName=localStorage.getItem("keyName");
var strPass=localStorage.getItem("keyPass");
if(strName){
$$("txtName").value=strName;
}
if(strPass){
$$("txtPass").value=strPass;
}
}
function btn_click() {
var strName=$$("txtName").value;
var strPass=$$("txtPass").value;
localStorage.setItem("keyName",strName);
if($$("chkSave").checked){
localStorage.setItem("keyPass",strPass);
}else{
localStorage.removeItem("keyPass");
}
if (document.cookie.indexOf("user=new") === -1) {
alert('注册成功!');
var t = new Date(new Date().getTime() + 1000 * 60 * 60 * 24 * 30);
document.cookie = "user=new; expires=" + t.toGMTString();
window.location.href='1.html'
}else{
alert('登录成功!');
window.location.href='1.html'
}
}
</script>
32、34、35、36这四行是利用了cookie的原理,判断此电脑/此用户是否是第一次进入这个页面,或是第一次点击这个按钮,若是,则让电脑“记住”这个举动。
然后在另一个页面(主页面)中从localStorage中调用keyName值:
<li id="np2">欢迎您:<t id="t1"></t>
<ul>
<li><a href="#" id="a1">退出登录</a> </li>
</ul>
</li>
<script>
if(localStorage.getItem("keyName")){
document.getElementById("np1").style.display="none";
document.getElementById("np2").style.display="block";
var strName=localStorage.getItem("keyName");
document.getElementById("t1").innerHTML=strName;
document.getElementById('a1').addEventListener('click',function(){
localStorage.removeItem("keyName");
document.getElementById("np2").style.display="none";
document.getElementById("np1").style.display="block";
})
}
</script>
即可!
localStorage与sessionStorage的区别在于数据的生存周期。对于localStorage中存储的数据来说,只要没被显式的删除,即一直存在
以下是更新内容↓
最近重温es6标准,一些以往没有注意过的内容映入眼帘,比如 —— Proxy。
Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”。其基本格式:
let target = new Proxy(target,handle);
其中,new Proxy()表示生成一个Proxy实例,target参数表示所要拦截的目标对象,handler参数也是一个对象,用来定制拦截行为。
Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。
那么问题来了,你有没有在页面上遇到过大量数据的“缓存”?你是否会对重复不断的 storage.getItem/setItem
感到苦恼?
现在有了代理proxy,这些问题就迎刃而解了:
proxy的特别之处在于:它只监听最外面的大的对象,只要改的是里面的数据 —— 不管是直接对象还是对象的属性值,它都会被触发。
比如这段代码中无论是改data中的name的值,还是改data中的message中的address的值,都会触发data监听的改变:
data:{
name:'mxc',
message:{
address:'xxxx'
}
}
基于此,我们能不能写一个针对某对象的监听器,然后把所有需要缓存的对象都放在里面引用,这样不就告别了一些无意义的重复操作?
let storage_test={name:"mxc"};
storage_test=new Proxy(storage_test,{
//target是指监听对象,value是指监听属性的属性名
get(target,value){
let storage_value;
if(localStorage.getItem(value)){
if((typeof localStorage.getItem(value)).toLocaleLowerCase()==='object'){
storage_value=JSON.parse(localStorage.getItem(value))
}else{
storage_value=localStorage.getItem(value)
}
return storage_value
}else{
if((typeof target[value]).toLocaleLowerCase()==='function'){
return target.target.bind(target)
}else{
return target[value]
}
}
},
//target是指监听对象,key是指属性名,value是指要填写的属性值
set(target,key,value){
target[key]=value;
if((typeof value).toLocaleLowerCase()==='object'){
localStorage.setItem(key,JSON.stringify(value))
}else{
localStorage.setItem(key,value)
}
return true
}
});
console.log(storage_test.name)
storage_test.name=[1,3,2,4,5]
console.log(storage_test.name)
这里需要注意的是:proxy实例的set函数需要有明确的返回值 —— true/false。否则在严格模式下会报错!
源
再啰嗦几句:同源策略
这个名词想必大家都听过。很头大的一个定义。(是指在实际操作/项目中,当然,Android开发的同行们完全不必考虑了,,,羡慕)
源是指由协议、主机名、端口号所组成的标识符。在Web Storage中保存的数据只能在同一个源中执行的程序所共享。不同源之间不能操作。
比如:
http://cixnsb.cn/mxc/UCgzs/1.html //原页面
http://cixnsb.cn/mxc/UCgzs/2.html //同源
http:cjxnsb.cn/ly/uc/1.html //跨源