在开发过程中,我们难免会遇到token存储、代码缓存、图片存储等,以及其他可能存在的前端存储问题。今天我们从浏览器存储入手,从前端的角度来了解一下缓存的应用场景,以及在日常开发中,哪些地方需要缓存,使用缓存可以带来哪些优势或者bug1.什么是本地存储客户端数据存储?可以使用本地存储用户的临时登录信息、用户页面配置、当前临时信息等用户想保存的东西,下次访问可以继续使用,但是服务器不需要浪费空间来存储这些信息,这时候可以应用Localstorage,存储在用户的本地2.H5之前如何实现本地存储1.先锋userData:只有IE支持XML文件userData来服务IE。单个文件的大小限制为128kb,一个域名下总共可以保存1024kb的文件。微软给他提供了相应的API,但是不符合W3C规范,平台支持不够广,这里略过。2、Cookie:会携带在http请求的header上,安全问题大小为4k。主要域污染是一个常见的应用场景,它是判断用户是否登录。比如登录一个网站,可以看到“记住密码”,这通常是通过存储一块来实现的在cookie中识别用户身份的数据。对于已经登录的用户,服务器会在他登录时在cookie中插入一个加密的唯一标识码,下次只需要读取这个值就可以判断当前用户是否登录了。优点:兼容性最好,几乎所有浏览器都支持缺点:大小限制很小,每次发送HTTP请求时,请求头都会携带Cookie信息,会带来安全问题,因为cookie会被带入http请求的内容中,如果大量使用,请求包可能会越来越大,导致请求速度变慢,影响用户体验,当然cookies可以尽量简化。cookie可以手动设置或由服务器生成。当客户端(浏览器)向服务器发送请求时,服务器会向客户端反馈一些信息。此信息的键/值由浏览器保存为客户端特定文件夹中的文件。cookie保存在浏览器中,以百度为例://storecookieletsetCookie=(name,value,times)=>{letdate=newDate()data.setDate(data.getDate()+times)document.cookie=name+'='+value+';expires='+date}//getcookieletgetCookie=(name)=>{letcookies=document.cookieletcookieArr=cookies.split(';')||[]if(!cookieArr.length)返回''for(leti=0;i{//通过建立cookie的时间设置,将时间设置提前一天,从而强制cookie无效,最终达到删除cookie的目的setCookie(name,'','-1')}3.基于HTML5规范的WebStorageHTML5提供了两种新的客户端存储数据的方法:sessionStorage会话存储localStorage本地存储WebStorage存储解决cookie带来的一些问题限制:解决4K大小问题解决请求头中存储信息问题解决关系存储问题跨浏览器WebStorage本地存储,数据不通过服务器传输request,所以它可以存储大量数据而不影响网站性能。比如在客户端保存一些用户行为或者数据,如果遇到一些内容很多的表单,为了优化用户体验,我们可以将表单页面拆分成多个子页面,然后引导用户按步骤填写。这个时候,sessionStorage的作用就出来了。或者从接口中获取的一些短期内不会更新的数据,我们也可以使用WebStorage来存储。1.SessionStorage临时存储神器优点:临时的,自动回收关闭的页面标签,两个不同标签页的sessionStorage是不共享的缺点:临时的,因为是临时的,不能存储持久化的东西2.localstorage永久级存储的优点:兼容性适中,几乎现代浏览器都支持,无过期时间限制,永久存储,永不失效,即只要不卸载浏览器,数据就会一直存在,除非手动删除缺点:有大小限制,IE9,IE10不支持localstorage过期时间限制代码如下:set(key,val){constcurTime=newDate().getTime()localStorage.setItem(key,JSON.stringify({data:val,time:curTime}))},get(key){constdata=localStorage.getItem(key)constdataObj=JSON.parse(data)if(newDate().getTime()-dataObj.time<0){console.log('expires')}else{console.log('expirdata='+dataObj.data)}}3.LocalStorage和sessionStorage相同:5MB左右(不同浏览器有差异),操作简单,类似于key/value存储方法;安装在窗口对象上;不同:保存数据的生命周期不同:localStorage中保存的数据没有过期时间设置,在浏览器打开期间一直保存,重新加载或关闭再打开浏览器后才能获取,而sessionStorage中保存的数据数据将在页面会话结束时被清除;localStorage的数据不能跨浏览器获取,sessionStorage不能跨页面交互,只在当前页面有效。4.属性和方法介绍:length获取存储数据的个数除了length属性和自定义属性外,其他属性和方法都在原型中(注意:obj是localStorage或sessionStorage):key(index)获取的个数存储数据索引键名obj.setItem(key,value)||obj.key=值||obj[key]=value存储的数据value的键名是key,如果键名存在,会覆盖对应的值obj。getIem(键)||对象键||obj[key]获取指定键名对应的值obj.removeItem(key)移除指定键名对应的数据obj.clear()清除本地存储中的所有数据5.可以存储什么内容?数组、json数据、图片、脚本、样式文件存储图片如下:setImg(key){constimg=document.createElement('img')img.src='./1323_2071n.png'img.addEventListener('load',function(){//加载图片时触发回调函数constimgCanvas=document.createElement('canvas')constimgContext=imgCanvas.getContext('2d')//确保canvas元素的大小为与图片大小一致imgCanvas.width=this.widthimgCanvas.height=this.height//渲染图片到canvasimgContext.drawImage(this,0,0,this.width,this.height)//使用数据url提取constimgAsDataURL=imgCanvas.toDataURL('image/png')//保存在本地存储尝试{localStorage.setItem(key,imgAsDataURL)}catch(error){console.log(error)}})},getImg(key){constsrcStr=localStorage.getItem(key)constimgObj=document.createElement('img')imgObj.src=srcStrdocument.getElementById('body').appendChild(imgObj)}如果有些图片不经常变化,存在localstorage中,用户第二次访问时可以快速访问,但是如果图片资源较大,6.使用注意事项:使用前需先确定浏览器是否支持手机浏览器。比如IOS开启incognito模式,就无法访??问localstorage。还有一些浏览器可以访问存储在localstorage中的对象,但是存储的时候会报错。这时候设置localstorage就可以捕获到异常。如果捕获到异常,说明浏览器写入数据时不支持localstorage,需要异常处理。,避免超过容量而抛出错误trycatch如果超过存储大小,可以使用一些算法,例如LRU,FIFO来处理旧数据,避免使用它们来存储系统中的敏感数据。不是所有数据都适合cookie、localStorage、sessionStorage,因为只要打开控制台,就可以随意修改它们的值。如果网站中的代码有xss注入的风险,他们可以对你存储的数据做任何事情。过期控制:localstorage没有过期时间限制。如果需要有过期限制,需要增加过期业务处理机制。密钥的唯一性。如果有重复的键,它将被覆盖。存储数据不能在子域之间共享。如何在服务器端获取4.indexedDB数据库是一种可以在浏览器中持久化存储结构化数据的数据库,为Web应用提供丰富的查询能力。存储结构:indexedDB按域名分配独立空间。一个数据库可以创建多个对象存储空间(表),一个对象存储空间可以存储多个对象数据。总之,indexedDB提供了一种类数据库的数据存储和使用方式,类似于NoSQL,非常强大,支持所有的处理和健壮的查询能力。当需要存储大量数据时,indexedDB显然更适合,但其API相对复杂。更多indexedDB的特性和使用方法,请点击这里