国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > HTML > 正文

HTML5中Localstorage的使用教程

2020-03-24 17:13:44
字體:
供稿:網(wǎng)友
什么是localstorage 前幾天在老項目中發(fā)現(xiàn)有對cookie的操作覺得很奇怪,咨詢下來是要緩存一些信息,以避免在URL上面?zhèn)鬟f參數(shù),但沒有考慮過cookie會帶來什么問題: ① cookie大小限制在4k左右,不適合存業(yè)務(wù)數(shù)據(jù)
② cookie每次隨HTTP事務(wù)一起發(fā)送,浪費帶寬 我們是做移動項目的,所以這里真實適合使用的技術(shù)是localstorage,localstorage可以說是對cookie的優(yōu)化,使用它可以方便在客戶端存儲數(shù)據(jù),并且不會隨著HTTP傳輸,但也不是沒有問題: ① localstorage大小限制在500萬字符左右,各個瀏覽器不一致
② localstorage在隱私模式下不可讀取
③ localstorage本質(zhì)是在讀寫文件,數(shù)據(jù)多的話會比較卡(firefox會一次性將數(shù)據(jù)導(dǎo)入內(nèi)存,想想就覺得嚇人啊)
④ localstorage不能被爬蟲爬取,不要用它完全取代URL傳參 瑕不掩瑜,以上問題皆可避免,所以我們的關(guān)注點應(yīng)該放在如何使用localstorage上,并且是如何正確使用。
localstorage的使用
基礎(chǔ)知識 localstorage存儲對象分為兩種: ① sessionStrage: session即會話的意思,在這里的session是指用戶瀏覽某個網(wǎng)站時,從進入網(wǎng)站到關(guān)閉網(wǎng)站這個時間段,session對象的有效期就只有這么長。 ② localStorage: 將數(shù)據(jù)保存在客戶端硬件設(shè)備上,不管它是什么,意思就是下次打開計算機時候數(shù)據(jù)還在。 兩者區(qū)別就是一個作為臨時保存,一個長期保存。 這里來一段簡單的代碼說明其基本使用: XML/HTML Code復(fù)制內(nèi)容到剪貼板
divid= msg 'msg'), text=document.getElementById('text'), type=document.getElementById('type'); functionsave(){ varstr=text.html' target='_blank'>value; vart=type.value; if(t=='session'){ sessionStorage.setItem('msg',str); }else{ localStorage.setItem('msg',str); } } functionload(){ vart=type.value; if(t=='session'){ msg.innerHTML=sessionStorage.getItem('msg'); }else{ msg.innerHTML=localStorage.getItem('msg'); } } /script
實際工作中對localstorage的使用一般有以下需求: ① 緩存一般信息,如搜索頁的出發(fā)城市,達到城市,非實時定位信息 ② 緩存城市列表數(shù)據(jù),這個數(shù)據(jù)往往比較大 ③ 每條緩存信息需要可追蹤,比如服務(wù)器通知城市數(shù)據(jù)更新,這個時候在最近一次訪問的時候要自動設(shè)置過期 ④ 每條信息具有過期日期狀態(tài),在過期外時間需要由服務(wù)器拉取數(shù)據(jù)XML/HTML Code復(fù)制內(nèi)容到剪貼板
//代理對象,默認為localstorage this.sProxy=window.localStorage; //60*60*24*30*1000ms==30天 this.defaultLifeTime=2592000000; //本地緩存用以存放所有l(wèi)ocalstorage鍵值與過期日期的映射 this.keyCache='SYSTEM_KEY_TIMEOUT_MAP'; //當緩存容量已滿,每次刪除的緩存數(shù) this.removeNum=5; }, assert:function(){ if(this.sProxy===null){ throw'notoverridesProxyproperty'; } }, initialize:function(opts){ this.propertys(); this.assert(); }, /* 新增localstorage 數(shù)據(jù)格式包括唯一鍵值,json字符串,過期日期,存入日期 sign為格式化后的請求參數(shù),用于同一請求不同參數(shù)時候返回新數(shù)據(jù),比如列表為北京的城市,后切換為上海,會判斷tag不同而更新緩存數(shù)據(jù),tag相當于簽名 每一鍵值只會緩存一條信息 */ set:function(key,value,timeout,sign){ var_d=newDate(); //存入日期 varindate=_d.getTime(); //最終保存的數(shù)據(jù) varentity=null; if(!timeout){ _d.setTime(_d.getTime()+this.defaultLifeTime); timeout=_d.getTime(); } // this.setKeyCache(key,timeout); entity=this.buildStorageObj(value,indate,timeout,sign); try{ this.sProxy.setItem(key,JSON.stringify(entity)); returntrue; }catch(e){ //localstorage寫滿時,全清掉 if(e.name=='QuotaExceededError'){ //this.sProxy.clear(); //localstorage寫滿時,選擇離過期時間最近的數(shù)據(jù)刪除,這樣也會有些影響,但是感覺比全清除好些,如果緩存過多,此過程比較耗時,100ms以內(nèi) if(!this.removeLastCache())throw'本次數(shù)據(jù)存儲量過大'; this.set(key,value,timeout,sign); } console console.log(e); } returnfalse; }, //刪除過期緩存 removeOverdueCache:function(){ vartmpObj=null,i,len; varnow=newDate().getTime(); //取出鍵值對 varcacheStr=this.sProxy.getItem(this.keyCache); varcacheMap=[]; varnewMap=[]; if(!cacheStr){ return; } cacheMap=JSON.parse(cacheStr); for(i=0,len=cacheMap.length;i len;i++){ tmpObj=cacheMap[i]; if(tmpObj.timeout now){ this.sProxy.removeItem(tmpObj.key); }else{ newMap.push(tmpObj); } } this.sProxy.setItem(this.keyCache,JSON.stringify(newMap)); }, removeLastCache:function(){ vari,len; varnum=this.removeNum||5; //取出鍵值對 varcacheStr=this.sProxy.getItem(this.keyCache); varcacheMap=[]; vardelMap=[]; //說明本次存儲過大 if(!cacheStr)returnfalse; cacheMap.sort(function(a,b){ returna.timeout-b.timeout; }); //刪除了哪些數(shù)據(jù) delMap=cacheMap.splice(0,num); for(i=0,len=delMap.length;i len;i++){ this.sProxy.removeItem(delMap[i].key); } this.sProxy.setItem(this.keyCache,JSON.stringify(cacheMap)); returntrue; }, setKeyCache:function(key,timeout){ if(!key||!timeout||timeout newDate().getTime())return; vari,len,tmpObj; //獲取當前已經(jīng)緩存的鍵值字符串 varoldstr=this.sProxy.getItem(this.keyCache); varoldMap=[]; //當前key是否已經(jīng)存在 varflag=false; varobj={}; obj.key=key; obj.timeout=timeout; if(oldstr){ oldMap=JSON.parse(oldstr); if(!_.isArray(oldMap))oldMap=[]; } for(i=0,len=oldMap.length;i len;i++){ tmpObj=oldMap[i]; if(tmpObj.key==key){ oldMap[i]=obj; flag=true; break; } } if(!flag)oldMap.push(obj); //最后將新數(shù)組放到緩存中 this.sProxy.setItem(this.keyCache,JSON.stringify(oldMap)); }, buildStorageObj:function(value,indate,timeout,sign){ varobj={ value:value, timeout:timeout, sign:sign, indate:indate }; returnobj; }, get:function(key,sign){ varresult,now=newDate().getTime(); try{ result=this.sProxy.getItem(key); if(!result)returnnull; result=JSON.parse(result); //數(shù)據(jù)過期 if(result.timeout now)returnnull; //需要驗證簽名 if(sign){ if(sign===result.sign) returnresult.value; returnnull; }else{ returnresult.value; } }catch(e){ console console.log(e); } returnnull; }, //獲取簽名 getSign:function(key){ varresult,sign=null; try{ result=this.sProxy.getItem(key); if(result){ result=JSON.parse(result); sign=result result.sign } }catch(e){ console console.log(e); } returnsign; }, remove:function(key){ returnthis.sProxy.removeItem(key); }, clear:function(){ this.sProxy.clear(); } }); Storage.getInstance=function(){ if(this.instance){ returnthis.instance; }else{ returnthis.instance=newthis(); } }; returnStorage; });
這段代碼包含了localstorage的基本操作,并且對以上問題做了處理,而真實的使用還要再抽象:
XML/HTML Code復(fù)制內(nèi)容到剪貼板
define(['AbstractStorage'],function(AbstractStorage){ varStore=_.inherit({ //默認屬性 propertys:function(){ //每個對象一定要具有存儲鍵,并且不能重復(fù) this.key=null; //默認一條數(shù)據(jù)的生命周期,S為秒,M為分,D為天 this.lifeTime='30M'; //默認返回數(shù)據(jù) //this.defaultData=null; //代理對象,localstorage對象 this.sProxy=newAbstractStorage(); }, setOption:function(options){ _.extend(this,options); }, assert:function(){ if(this.key===null){ throw'notoverridekeyproperty'; } if(this.sProxy===null){ throw'notoverridesProxyproperty'; } }, initialize:function(opts){ this.propertys(); this.setOption(opts); this.assert(); }, _getLifeTime:function(){ vartimeout=0; varstr=this.lifeTime; varunit=str.charAt(str.length-1); varnum=str.substring(0,str.length-1); varMap={ D:86400, H:3600, M:60, S:1 }; if(typeofunit=='string'){ unitunit=unit.toUpperCase(); } timeout=num; if(unit)timeout=Map[unit]; //單位為毫秒 returnnum*timeout*1000; }, //緩存數(shù)據(jù) set:function(value,sign){ //獲取過期時間 vartimeout=newDate(); timeout.setTime(timeout.getTime()+this._getLifeTime()); this.sProxy.set(this.key,value,timeout.getTime(),sign); }, //設(shè)置單個屬性 setAttr:function(name,value,sign){ varkey,obj; if(_.isObject(name)){ for(keyinname){ if(name.hasOwnProperty(key))this.setAttr(k,name[k],value); } return; } if(!sign)sign=this.getSign(); //獲取當前對象 obj=this.get(sign)||{}; if(!obj)return; obj[name]=value; this.set(obj,sign); }, getSign:function(){ returnthis.sProxy.getSign(this.key); }, remove:function(){ this.sProxy.remove(this.key); }, removeAttr:function(attrName){ varobj=this.get()||{}; if(obj[attrName]){ deleteobj[attrName]; } this.set(obj); }, get:function(sign){ varresult=[],isEmpty=true,a; varobj=this.sProxy.get(this.key,sign); vartype=typeofobj; varo={'string':true,'number':true,'boolean':true}; if(o[type])returnobj; if(_.isArray(obj)){ for(vari=0,len=obj.length;i len;i++){ result[i]=obj[i]; } }elseif(_.isObject(obj)){ result=obj; } for(ainresult){ isEmpty=false; break; } return!isEmpty?result:null; }, getAttr:function(attrName,tag){ varobj=this.get(tag); varattrVal=null; if(obj){ attrVal=obj[attrName]; } returnattrVal; } }); Store.getInstance=function(){ if(this.instance){ returnthis.instance; }else{ returnthis.instance=newthis(); } }; returnStore; });
我們真實使用的時候是使用store這個類操作localstorage,代碼結(jié)束簡單測試:
存儲完成,以后都不會走請求,于是今天的代碼基本結(jié)束 ,最后在android Hybrid中有一后退按鈕,此按鈕一旦按下會回到上一個頁面,這個時候里面的localstorage可能會讀取失效!一個簡單不靠譜的解決方案是在webapp中加入:XML/HTML Code復(fù)制內(nèi)容到剪貼板
window.onunload=function(){};//適合單頁應(yīng)用,不要問我為什么,我也不知道
結(jié)語 localstorage是移動開發(fā)必不可少的技術(shù)點,需要深入了解,具體業(yè)務(wù)代碼后續(xù)會放到git上,有興趣的朋友可以去了解
html教程

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 柘城县| 临安市| 江源县| 娄底市| 浪卡子县| 漳平市| 沁源县| 乐山市| 兴海县| 宝山区| 东至县| 龙海市| 江永县| 十堰市| 张家港市| 河东区| 新龙县| 连城县| 锡林浩特市| 荆州市| 岚皋县| 井冈山市| 利津县| 汉川市| 临沧市| 灵石县| 榆树市| 巴彦县| 安化县| 淳化县| 廊坊市| 天峻县| 安义县| 乌拉特前旗| 大石桥市| 凉山| 安国市| 蚌埠市| 仪陇县| 南城县| 蚌埠市|