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