浅谈web存储
1、先来说说之前的客户端存储吧~在html5出来之前~客户端存储主要是使用cookie~不过这种古老的方式存在着好一些弊端~举例如下:
可以存储的数据的大小受到限制~官方指出一个域名下最多可以存储4k的数据(有点少吧~~)
cookie的数据放到了http请求头上~这样不仅使得http请求头变得臃肿~过多的cookie会使请求越来越慢~同时还带来了安全的问题~这玩意默认是明文的
同时注意cookie是会过期的~
2、还有一种存储方式是userData~但是这个只有ie支持~考虑到平台的限制~此处不再赘述~
3、html5出来后~web存储克服了之前cookie的缺陷~比如大小限制从原来的4k编程了5M~也有很好的跨平台的支持~下面我们来看下其主要的方式:
sessionStorage/localStorage:二者的主要区别是sessionStorage存储的数据在本次会话窗口被关闭后就没有了~而localStorage中存储的数据是长期存在的~除非手动删除~同时~同一站点下的不同的会话窗口(注意~是同一站点~不是同域名~localStorage的数据就算是同一域名下的子域名也不可以共享)可以共享localStorage中存储的数据~再者~Safari浏览器还支持localStorage的一个事件~叫storage事件~这个事件是当localStorage中存储的数据发生变化时被触发的~利用这个事件~同一站点下的不同窗口中localStorage的数据就可以实现无刷新的同步啦~比如我打开两个京东的页面~在第一个页面把商品加入购物车~第二个页面无需刷新~购物扯中的数据就会自动更新~无奈~这么棒的功能目前只有Safar支持~~还有一点需要注意的是这个事件虽然在losalStorage中提出~但这个事件的拥有着是window对象~只要页面添加了这个事件~window会自动在localStorage中存储的数据发生变化时触发同一站点的窗口~而不是同一站点的会话窗口会被忽略~
应用:使用localStorage实现图片的存储方法:
js代码:
function saveImg() { var myImg = document.createElement("img"); myImg.src = "http://127.0.0.1/x.jpg"; //当图片加载完成的时候触发回调函数 myImg.addEventListener("load", function () { var imgCanvas = document.createElement("canvas"), imgContext = imgCanvas.getContext("2d"); // 确保canvas元素的大小和图片尺寸一致 imgCanvas.width = this.width; imgCanvas.height = this.height; // 渲染图片到canvas中 imgContext.drawImage(this, 0, 0, this.width, this.height); // 用data url的形式取出 var imgAsDataURL = imgCanvas.toDataURL("image/png"); // 保存到本地存储中 try { localStorage.setItem("elephant", imgAsDataURL); } catch (e) { console.log("Storage failed: " + e); } }, false); } function getImg() { var imgData = localStorage.getItem("elephant"); var imgObj = document.createElement("img"); imgObj.src = imgData; document.body.appendChild(imgObj); }
注意:因为本地存储只能存储字符串~所以这里使用了canvas来对图片数据做一个转换~但是canvas有一个安全策略~当请求的的图片和当前的页面不是同一个域名时会报错~所以这里我使用xampp搭建了一个服务器~把图片和测试页面都丢进去~以此来测试页面的运行~
另外注意一下~使用localStorage前强烈建议先判断当前浏览器是否支持~网上指出的一个通用的方法是if(window.localStorage)~但是这里建议使用一种更为健全的方式:即使用上面的方式~直接localStorage.setItem一下~并把这句放到try-catch块中去执行~如果捕获到异常~就说明当前的浏览器不支持localStorage~那么我们直接就换别的方法来做这个存储啦
下面谈谈localStorage的缺陷~一个是它没有过期这么个说法~只要不手动删除~那数据将会永久保存~如果业务中涉及到数据保存需要设置期限~那我们可以自己封装相应的数据对象到localStorage中来实现~下面是一个实现带过期效果的localStorage的demo
function saveDataWithDate(key, value) { var currentTime = new Date().getTime(); try { localStorage.setItem(key, JSON.stringify({data: value,time: currentTime})); }catch(e) { console.log("Storage failed: " + e); } } function getDataWithDate(key, lastTime) { //lastTime为期限 var data = localStorage.getItem(key); var dataObj = JSON.parse(data); console.log(dataObj.time); if(new Date().getTime() - dataObj.time > lastTime) { console.log("数据已过期"); }else { console.log("data is:" + dataObj.data); } }