HTML5项目笔记7:使用HTML5 WebStorage API构建与.NET对应的会话机制
HTML5的Web Storage API,我们也称为DOMStarage API,用于在Web请求之间持久化数据。在Web Starage API 出现之前,我们都是将客户端和服务端之间的交互数据存储在远程服务器上,随着Web Starage API的出现,我们可以在客户端存储我们重复访问的交互数据,用户在打开浏览器的时候,可以快速地读取到数据,减少了用户等待,数据流量。
在Web Starage 出现之前,我们在客户端存储数据一般使用Cookie,用于客户端和服务端之间保存会话标识符,同时可以将本地个性化数据保存在应用程序中。Cookie的受限在它的存储大小只有4KB,不可能存储大数据;cookie在请求情况下透明地在服务器和浏览器中传送数据,在没加密的情况下数据存在安全风险。
相比之下,Web Starage API 用Jsvascript来保存对象,在页面中加载,读取和保存数据都比较简易,存储的数据不在网络上传输,而且可以保存高达几兆字节的数据。无疑是我们客户端数据临时存储的利器。
浏览器支持情况
浏览器类型 |
版本号 |
Chrome |
3.0版本及以上 |
FireFox |
3.0版本及以上 |
Internet Explorer |
8.0版本及以上 |
Ppera |
10.5版本及以上 |
Safari |
4.0版本及以上 |
使用 sessionStorage 操作数据:
设置数据:
window.sessionStorage.setItem(“UserName”,”Ben”); 或者
window.sessionStorage.UserName = “Ben”;
获取数据:
var UserName = window.sessionStorage.getItem(“UserName”); 或者
var UserName = window.sessionStorage.UserName;
删除数据:
window.sessionStorage.removeItem(“UserName”);
清空数据:
window.sessionStorage.clear();
sessionStorage 的生命周期值存在于浏览器窗口或者页面标签,一旦关闭浏览器或者页面标签,数据也就丢失了,所以它更应该被认为是页面间的会话标识。
数据隔离,不同的浏览器页面或者标签来说,数据会跨页面保存,但是不会泄漏。
使用 localStorage 设置或获取数据:
设置数据:
window.localStorage.setItem(“UserName”,”Ben”); 或者
window.localStorage.UserName = “Ben”;
获取数据:
var UserName = window.localStorage.getItem(“UserName”); 或者
var UserName = window.localStorage.UserName;
删除数据:
window.localStorage.removeItem(“UserName”);
清空数据:
window.localStorage.clear();
sessionStorage 和 localStorage的比较:
sessionStorage |
localStorage |
数据保存直至存储它的窗口或标签页面关闭 |
数据的生命周期比窗口或浏览器的生命周期长 |
数据只在构建它的窗口或者标枪页中有效 |
数据可被同源的窗口和标签页共享 |
由上,可见 localStorage 的生命周期更长,存储范围更广,可用于多个浏览器窗口和标签页或多个视图之间的数据存储和共享。
构建与.NET对应的会话机制:
当我们的HTML5客户端应用程序要与.Net的后台程序对接上的时候,就要构建与之对应的会话机制,这样才能达成一致的操作:
我们来看看.net的session 会话机制,它是由服务端创建,并分配一个sessionid,然后“告诉”给客户端,而客户端在每次访问的时候都会把这个session信息放到http头中发送出去,在服务端有个session列表,存了所有的session的相关信息,包括session的timeout信息。
在之前的IE6版本:
打开IE登陆一个账号a。把这个IE叫做IE1.
从桌面上重新打开一个IE。登陆账号b。这个IE就是b账号的session。这个IE叫做IE2
IE1和IE2记录的session是不一样的。之间的session不影响。
IE7之后的这种标签浏览器。一个IE中打开的所有标签,甚至打开多个IE都是共享一个session。
继续上面的操作。我们用IE1的菜单栏“文件”-“新建”-“窗口”新建一个IE,叫他IE3。由于IE3是从IE1来的。因此IE3继承了IE1的session。当你用IE3登陆账号c的时候。IE1、IE3的session都是账号c。。。然后用IE1登陆账号d。IE1、IE3登陆的账号session就成了账号d的session。
谷歌Chrome浏览器打开时候它的所有标签页或者打开多个Chrome都是共享一个Session的,Session结束由会话时间TimeOut的超时和整个应用程序的生命结束所决定的。
这个规则决定同一台机器上的同源浏览器上是不能够同时操作多个用户的程序的。这边说的是同源浏览器,也就是说你用IE打开一个应用程序,用Chrome打开一个应用程序,他们的Session是隔离的,没有联系的。
我们这边做一个测试,在项目中建两个aspx页面,一个页面为PageOne.aspx,一个页面为
PageTwo.aspx,他们使用同一个Session,Session["UserName"]
如图,在PageOne页面保存Session["UserName"]的值为Ben:
在PageTwo页面中显示也是Ben:
所以离线系统也采取了相同的策略:采用localStorage处理会话机制
localStorage |
数据的生命周期比窗口或浏览器的生命周期长 |
数据可被同源的每个窗口、标签页面或同时打开的浏览器共享 |
所以我们采用localStorage记录会话机制,用HTML5 的storage事件监听会话的变化:
1、 在用户登录的时候记录会话:
window.localStorage.setItem("sessionMechanism", username);
2、 在其他表单页面设置事件监听:
window.addEventListener("storage", checkStorageEvent, true);
function checkStorageEvent(e) {
if (e.key == "sessionMechanism") {
alert("登陆超时!,帐号" + e.newValue + "正在登录!");
window.location.href = "../login.htm";
}
}
一旦有第二个用户登录,不管是同一个浏览器的不同标签页还是不同的浏览器窗口,之前的用户就会超时,并返回到登录页面…
这样就保证了我们在同源的浏览器里面一次只能有一个账户在登陆操作,如果其他用户登录,当前用户就会被迫下线。这样避免了前后端的用户不一致导致的错误,我们之后会讲到跨域通信,离线系统和在线系统的交互,所以在线和离线的登录用户必须保持一致。
这边我们将这个会话机制应用到我们的系统中:
现在做一个场景,在这边我们的登录页面上记录全局的localStorage,一旦登录成功就记录当前的用户,所以在login.htm页面上有这样一段代码:
window.localStorage.setItem("sessionMechanism", username);
登录成功之后到了我们的用户信息页面:
同时我们的localStorage就多出了这个键值对:
这时我们在登录页面登录另一个帐号Brand用户:
在用户信息的页面会弹出下面这个对话框,并跳转到登录页:
这样就保证了一个同源浏览器只有一个用户在执行操作。
本文源码:CRX_WebStorage