JavaScript客户端存储

navigator.online:浏览器是否连接到网络
常见的客户端存储有几种:第一种,Web存储,其中包含localStorage对象和sessionStorage对象;第二种,Cookie,其作为一种被服务端脚本使用的客户端存储机制。

一、localStorage和sessionStorage

1. 二者区别在于存储的有效期和作用域的不同:
localStorage存储的数据时永久性的,作用域是限定在文档源级别的(文档源是通过协议、主机、端口三者确定)。注意其作用域也受到浏览器供应商限制。
sessionStorage作用域也是限定在文档源中,因此非同源文档无法共享sessionStorage,不仅如此,其作用域还被限定在窗口中(顶级窗口)。一个浏览器标签页包含两个iframe是可以共享的。
[javascript]  view plain  copy
  1. localStorage.setItem("x",1);    //以“x”的名字存储一个数值  
  2. localStorage.getItem("x");  //获取数值  
  3.   
  4. for(var i=0;i<localStorage.length;i++){  
  5.     var name = localStorage.key(i);  
  6.     var value = localStorage.getItem(name);  
  7. }  
  8.   
  9. localStorage.removeItem("x");   //删除“x”项  
  10. localStorage.clear();   //全部删除  
  11.   
  12. //存储对象的处理  
  13. var o = {x:1};  
  14. var oStr = JSON.stringify(o);   //由于存储的内容都是字符串,序列化对象  
  15. localStorage.setItem("o",oStr);  
  16. localStorage.getItem("o");  //{"x":1}   typeof类型:string  
  17. JSON.parse(localStorage.getItem("o")).x;    //反序列化  
  18.   
  19. // 识别使用哪种存储机制  
  20. var memory = window.localStorage || (window.UserDataStorage && new UserDataStorage()) || new CookieStorage();     
  21. // 然后在对应机制中获取数据  
  22. memory.getItem("name");  
2. 存储事件
无论什么时候存储在localStorage和sessionStorage的数据发生改变,浏览器都会在其他对该数据可见的窗口对象上触发存储事件(但是,在对数据进行改变的窗口对象上是不会触发的)。为存储事件注册处理程序可以通过addEventListener()方法(IE下使用addEvent()方法)。监听storage。
[javascript]  view plain  copy
  1. if(window.addEventListener){  
  2.     window.addEventListener("storage",handle_storage,false);  
  3. }else if(window.attachEvent){  
  4.     window.attachEvent("onstorage",handle_storage);  
  5. }  
  6.   
  7.   
  8. function handle_storage(e){  
  9.     if(!e){  
  10.         e=window.event;  
  11.     }  
  12.     //showStorage();  
  13. }  
对于事件变量e,是一个StorageEvent对象,提供了一些实用的属性,可以很好的观察键值对的变化
storageArea: 表示存储类型(Session或Local)
key:发生改变项的key
oldValue: key的原值
newValue:key的新值
url*:key改变发生的URL【使用url属性前,你应该先检查它是否存在,如果没有url属性,则应该使用uri属性】
最后需要注意的是,localStorage和存储事件都是采用广播机制,浏览器会对目前正在访问同样站点的所有窗口发送消息。

二、Cookie

绝大数浏览器可以通过navigator.cookieEnabled这个属性来检测Cookie是否启用!
Cookie的有效期和整个浏览器进程而不是单个浏览器窗口有效期一致。
默认情况下,cookie和创建它的WEB页面有关,并对该WEB页面以及和该WEB页面同目录或者子目录的其他WEB页面可见。
将cookie的路径设置为“/”等于是让cookie和localStorage拥有同样的作用域。
1. 保存cookie
cookie的名/值中的值是不允许包括分号、逗号和空白符,因此,在存储前一般可以采用JavaScript核心的全局函数encodeURIComponent()对值进行编码。

[javascript]  view plain  copy
  1. // 以name/value形式存储cookie  
  2. function setCookie(name,value,daysToLive){  
  3.     var cookie = name + "=" + encodeURIComponent(value);  
  4.     if(typeof daysToLive === 'number'){  
  5.         cookie += "; max-age=" + (daysToLive*60*60*24);  //分号空格  
  6.     }  
  7.     document.cookie = cookie;  
  8. }  
  9.   
  10. // 读取全部cookie  
  11. function getCookies(){  
  12.     var cookie = {};  
  13.     var all = document.cookie;  
  14.     if(all === ""){  
  15.         return cookie;  
  16.     }  
  17.     var list = all.split("; "); //注意有空格  
  18.     for(var i=0; i<list.length; i++){  
  19.         var item = list[i];  
  20.         var p = item.indexOf("="); //查找第一个“=”符号  
  21.         var name = item.substring(0,p);  
  22.         var value = item.substring(p+1);  
  23.         value = decodeURIComponent(value);  
  24.         cookie[name] = value;  
  25.     }  
  26.     return cookie;  
  27. }  
  28.   
  29. // 读取指定名称cookie项  
  30. function getCookie(name){  
  31.     var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)");  
  32.     if(arr=document.cookie.match(reg)){  
  33.         // unescape() 函数可对通过 escape() 编码的字符串进行解码  
  34.         // ECMAScript v3 已从标准中删除了 unescape() 函数,建议使用 decodeURI() 和 decodeURIComponent()   
  35.         //return unescape(arr[2]);  
  36.         return decodeURIComponent(arr[2]);  
  37.     }else {  
  38.         return null;  
  39.     };  
  40. //getCookie  
  41.   
  42. // 删除指定cookie项  
  43. function delCookie(name) {   
  44.     var exp = new Date();   
  45.     exp.setTime(exp.getTime() - 1); //有效期,为当前时间的前1s  
  46.     var cval=getCookie(name);   
  47.     if(cval!=null)   
  48.         // 把Date对象转换为"格林威治时间 (GMT)"形式的字符串  
  49.         document.cookie= name + "="+cval+";expires="+exp.toGMTString();    
  50. }   
  51.   
  52. // =======测试=========  
  53. setCookie('name',"ligang","100000");  
  54. setCookie('age',28,"100000");  
  55. console.log(getCookies()['name'])  
  56. var age = getCookie('age');  
  57. console.log(age)  
  58. delCookie('age');  
  59. console.log(getCookie('age'))  

三、应用程序缓存

首先建立一个清单,包含应用程序依赖的所有URL列表;然后,通过在应用程序在主HTML页面的<html>标签中设置manifest属性,指向到该清单文件即可。

[html]  view plain  copy
  1. <!DOCTYPE HTML>  
  2. <html manifest="myapp.appcache">  
  3. <head></head>  
  4. <body></body>  
  5. </html>  

#清单文件中的首行内容必须以"CACHE MANIFEST"字符串开头
#myapp.appcache 示例:
[html]  view plain  copy
  1. CACHE MANIFEST  
  2.   
  3. # myapp version 1(更新这个数字以便让浏览器重新下载这个文件)  
  4.   
  5. # 直接缓存的文件  
  6. CACHE:  
  7.     ../css/*      
  8.     ../js/site/*  
  9.   
  10.   
  11. # 必须在线访问  
  12. NETWORK:   
  13.     index.do  
  14.       
  15. # 替代方案【从网络中载入videos/路径下文件失败,会采用缓存资源offline_help.html来代替】    
  16. FALLBACK:    
  17.     vidoes/ offline_help.html  
注意,浏览器只检查清单文件,而不会去检查缓存的文件是否有更新。
在更新清单文件之后,用户必须载入应用两次才能保证最新的版本生效:第一次是从缓存中载入老版本随后更新缓存;第二次才从缓存中载入新的版本。
浏览器在更新缓存中会触发一些事件,可以根据这些事件来给反馈信息给用户:
[javascript]  view plain  copy
  1. applicationCache.onupdateready = function(){  
  2.     var reload = confirm("发现新版本,您是否更新?");  
  3.     if(reload) location.reload();  
  4. }  

四、离线Web应用

可以使用localStorage来存储应用数据,然后当在线的时候再将数据长传到服务器。
示例:一个简单的记事本程序
note.html:
[html]  view plain  copy
  1. <!DOCTYPE HTML>  
  2. <html>  
  3.     <head>  
  4.         <meta charset="utf-8">  
  5.         <title>note</title>  
  6.         <script src="note.js"></script>  
  7.         <style>  
  8.             #editor {width: 100%; height: 250px;}  
  9.             #statusline {width: 100%;}  
  10.         </style>  
  11.     </head>  
  12.     <body>  
  13.         <div id="toolbar">  
  14.             <button id="savebutton" onclick="save()">Save</button>  
  15.             <button onclick="sync();">Sync Note</button>  
  16.             <button onclick="applicationCache.update();">Update Application</button>  
  17.         </div>  
  18.         <textarea id="editor"></textarea>  
  19.         <div id="statusline"></div>  
  20.     </body>  
  21. </html>  

note.js:

[javascript]  view plain  copy
  1. // 全局变量  
  2. var editor,statusline,savebutton,idletimer;  
  3.   
  4. window.onload = function(){  
  5.     //第一次载入时,初始化本地存储  
  6.     if(localStorage.note == null) localStorage.note = "";  
  7.     if(localStorage.lastModified == null) localStorage.lastModified = 0;  
  8.     if(localStorage.lastSaved == null) localStorage.lastSaved =0;  
  9.   
  10.     // 查找元素,并初始化全局变量  
  11.     editor = document.getElementById("editor");  
  12.     statusline = document.getElementById("statusline");  
  13.     savebutton = document.getElementById("savebutton");  
  14.   
  15.     // 初始化编辑器,将保存的笔记数据填充为其内容  
  16.     editor.value = localStorage.note;  
  17.     // 同步前禁止编辑  
  18.     editor.disabled = true;  
  19.   
  20.     // 一旦文本区有内容输入  
  21.     editor.addEventListener("input"function(e){  
  22.         // 将新的值保存到localStorage中  
  23.         localStorage.note = editor.value;  
  24.         localStorage.lastModified = Date.now();  
  25.         // 重置闲置计时器  
  26.         if(idletimer) clearTimeout(idletimer);  
  27.         idletimer = setTimeout(save, 5000);  
  28.         // 启用保存按钮  
  29.         savebutton.disabled = false;  
  30.     },false);  
  31.   
  32.     // 每次载入应用程序时,尝试同步服务器  
  33.     sync();  
  34. };  
  35.   
  36. // 离开页面前保存数据到服务器  
  37. window.onbeforeunload = function(){  
  38.     if(localStorage.lastModified > localStroage.lastModified)  
  39.         save();  
  40. };  
  41.   
  42. // 离线时,通知用户  
  43. window.onoffline = function(){  
  44.     status("Offline");  
  45. };  
  46.   
  47. // 再次返回在线状态时,进行同步  
  48. window.ononline = function(){  
  49.     sync();  
  50. };  
  51.   
  52.   
  53. // 当有新版本应用的时候,提醒用户  
  54. // 这里我们也可以采用location.reload()方法来强制重新载入应用  
  55. window.applicationCache.onupdateready = function(){  
  56.     status("A new version of this application is available. Reload to run it.");  
  57. };  
  58.   
  59. // 当没有新版本的时候也通知用户  
  60. window.applicationCache.onnoupdate = function(){  
  61.     status("You are running the lasted version of the application.");  
  62. };  
  63.   
  64. // 用于在状态栏显示状态消息的一个函数  
  65. function status(msg){  
  66.     statusline.innerHTML = msg;  
  67. }  
  68.   
  69. // 每当笔记内容更新后,如果用户停止编辑超过5分钟,就会自动将笔记本上传到服务器(在线状态下)  
  70. function save(){  
  71.     if(idletimer) clearTimeout(idletimer);  
  72.     idletimer = null;  
  73.     if(navigator.onLine){  
  74.         var xhr = new XMLHttpRequest();  
  75.         xhr.open("PUT","http://localhost/sitesettings/getBadgeInfo.pt");  
  76.         xhr.send(editor.value);  
  77.         xhr.onload = function(){  
  78.             localStorage.lastSave = Date.now();  
  79.             savebutton.disabled = true;  
  80.         };  
  81.     }  
  82. }  
  83.   
  84. // 如果检查服务器端是否有新版本的笔记  
  85. // 如果没有,则将当前版本保存到服务器端  
  86. function sync(){  
  87.     if(navigator.onLine){  
  88.         var xhr = new XMLHttpRequest();  
  89.         xhr.open("GET","http://localhost/sitesettings/getBadgeInfo.pt");  
  90.         xhr.send();  
  91.         xhr.onload = function(){  
  92.             var remoteModTime = 0;  
  93.             if(xhr.status == 200){  
  94.                 var remoteModTime = xhr.getResponseHeader("Last-Modified");  
  95.                 remoteModTime = new Date(remoteModTime).getTime();  
  96.             }  
  97.             if(remoteModTime > localStorage.lastModified){  
  98.                 status("Newer note found on server.");  
  99.                 var useit = confirm("There is a newer verion of the note\n"+  
  100.                                      "on the server. Click Ok to use that version\n"+  
  101.                                      "or click Cancel to continue editing this\n"+  
  102.                                      "version and overwrite the server");  
  103.                 var now = Date.now();  
  104.                 if(useit){  
  105.                     editor.value = localStorage.note = xhr.responseText;  
  106.                     localStorage.lastSaved = now;  
  107.                     status("Newest version downloaded");  
  108.                 }else{  
  109.                     status("Ignoring newer version of the note.");  
  110.                 }  
  111.                 localStorage.lastModified = now;  
  112.             }else{  
  113.                 ststus("You are editing the current version of the note.");  
  114.             }  
  115.             if(localStorage.lastModified > localStorage.lastSaved){  
  116.                 save();  
  117.             }  
  118.             editor.disabled = false// 再次启用编辑器  
  119.             editor.focus(); // 将光标定位到编辑器中  
  120.         };  
  121.     }else{  
  122.         //离线状态下,不能同步  
  123.         status("Can't sync while offline");  
  124.         editor.disabled = false;  
  125.         editor.focus();  
  126.     }  
  127. }  
note.appcache:

[html]  view plain  copy
  1. CACHE MANIFEST  
  2. #note v1.0  
  3.   
  4. note.html  
  5. note.js  
  6.   
  7. NETWORK:  
  8. note  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值