Html5 引入了兩種機制,類似於 HTTP 的會話 cookIEs,用於在客戶端存儲結構化數據以及克服以下缺點。
每個 HTTP 請求中都包含 CookIEs,從而導致傳輸相同的數據減緩我們的 Web 應用程序。
每個 HTTP 請求中都包含 CookIEs,從而導致發送未加密的數據到互聯網上。
CookIEs 只能存儲有限的 4KB 數據,不足以存儲所需的數據。
這兩種存儲方式是 session storage 和 local storage,它們將用於處理不同的情況。
幾乎所有最新版的浏覽器都支持 Html5 存儲,包括 IE 浏覽器。
會話存儲
_會話存儲_被設計用於用戶執行單一事務的場景,但是同時可以在不同的窗口中執行多個事務。
示例
比如,如果用戶在同一網站的兩個不同的窗口中購買機票。如果該網站使用 cookIE 跟蹤用戶購買的機票,當用戶在窗口中點擊頁面時,從一個窗口到另一個時當前已經購買的機票會“洩漏”,這可能導致用戶購買同一航班的兩張機票而沒有注意到。
Html5 引入了 sessionStorage 屬性,這個網站可以用來把數據添加到會話存儲中,用戶仍然可以在打開的持有該會話的窗口中訪問同一站點的任意頁面,當關閉窗口時,會話也會丟失。
下面的代碼將會設置一個會話變量,然後訪問該變量:
XML/Html Code復制內容到剪貼板
- <!DOCTYPE Html>
- <Html>
- <body>
-
- <script type="text/Javascript">
- if( sessionStorage.hits ){
- sessionStorage.hits = Number(sessionStorage.hits) +1;
- }else{
- sessionStorage.hits = 1;
- }
- document.write("Total Hits :" + sessionStorage.hits );
- </script>
- <p>Refresh the page to increase number of hits.</p>
- <p>Close the window and open it again and check the result.</p>
-
- </body>
- </Html>
本地存儲
_本地存儲_被設計用於跨多個窗口進行存儲,並持續處在當前會話上。尤其是,出於性能的原因 Web 應用程序可能希望在客戶端存儲百萬字節的用戶數據,比如用戶撰寫的整個文檔或者是用戶的郵箱。
CookIEs 並不能很好的處理這種情況,因為每個請求都會傳輸。
示例
Html5 引入了 localStorage 屬性,可以用於訪問頁面的本地存儲區域而沒有時間限制,無論何時我們使用這個頁面的時候本地存儲都是可用的。
下面的代碼設置了一個本地存儲變量,每次訪問這個頁面時都可以訪問該變量,甚至是下次打開窗口時:
XML/Html Code復制內容到剪貼板
- <!DOCTYPE Html>
- <Html>
- <body>
-
- <script type="text/Javascript">
- if( localStorage.hits ){
- localStorage.hits = Number(localStorage.hits) +1;
- }else{
- localStorage.hits = 1;
- }
- document.write("Total Hits :" + localStorage.hits );
- </script>
- <p>Refresh the page to increase number of hits.</p>
- <p>Close the window and open it again and check the result.</p>
-
- </body>
- </Html>
便於學習上述概念 - 請進行在線練習。
刪除 Web 存儲
在本地機器上存儲敏感數據可能是危險的,可能會留下安全隱患。
_會話存儲數據_在會話終止之後將由浏覽器立即刪除。
要清除本地存儲設置需要調用 localStorage.remove('key');這個 'key' 就是我們想要移除的值對應的鍵。如果想要清除所有設置,需要調用 localStorage.clear() 方法。
下面的代碼會完全清除本地存儲:
XML/Html Code復制內容到剪貼板
- <!DOCTYPE Html>
- <Html>
- <body>
-
- <script type="text/Javascript">
- localStorage.clear();
-
- // Reset number of hits.
- if( localStorage.hits ){
- localStorage.hits = Number(localStorage.hits) +1;
- }else{
- localStorage.hits = 1;
- }
- document.write("Total Hits :" + localStorage.hits );
- </script>
- <p>Refreshing the page would not to increase hit counter.</p>
- <p>Close the window and open it again and check the result.</p>
-
- </body>
- </Html>
Web SQL 數據庫
Web SQL 數據庫 API 並不是 Html5 規范的一部分,但是它是一個獨立的規范,引入了一組使用 SQL 操作客戶端數據庫的 APIs。
核心方法
下面是規范中定義的三個核心方法。也會涵蓋在本教程中:
openDatabase:這個方法使用現有的數據庫或者新建的數據庫創建一個數據庫對象。
transaction:這個方法讓我們能夠控制一個事務,以及基於這種情況執行提交或者回滾。
executeSql:這個方法用於執行實際的 SQL 查詢。
開啟數據庫
如果數據庫已經存在,openDatabase 方法負責開啟數據庫,如果不存在,這個方法會創建它。
使用下面的代碼可以創建並開啟一個數據庫:
JavaScript Code復制內容到剪貼板
- var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024);
上面的方法接受下列五個參數:
數據庫名稱
版本號
描述文本
數據庫大小
創建回調
最後也是第五個參數,創建回調會在創建數據庫後被調用。然而,即使沒有這個特性(功能),運行時仍然會創建數據庫以及正確的版本。
執行查詢
執行查詢需要使用 database.transaction() 函數。這個函數需要一個參數,它是一個負責實際執行查詢的函數,如下所示:
JavaScript Code復制內容到剪貼板
- var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024);
- db.transaction(function (tx) {
- tx.executeSql('CREATE TABLE IF NOT EXISTS LOGS (id unique, log)');
- });
上面的查詢語句會在 'mydb' 數據庫中創建一個叫做的 LOGS 的表。
插入操作
為了在表中創建條目,我們在上面的例子中加入簡單的 SQL 查詢,如下所示:
JavaScript Code復制內容到剪貼板
- var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024);
- db.transaction(function (tx) {
- tx.executeSql('CREATE TABLE IF NOT EXISTS LOGS (id unique, log)');
- tx.executeSql('INSERT INTO LOGS (id, log) VALUES (1, "foobar")');
- tx.executeSql('INSERT INTO LOGS (id, log) VALUES (2, "logmsg")');
- });
創建條目時還可以傳遞如下所示的動態值:
JavaScript Code復制內容到剪貼板
- var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024);
- db.transaction(function (tx) {
- tx.executeSql('CREATE TABLE IF NOT EXISTS LOGS (id unique, log)');
- tx.executeSql('INSERT INTO LOGS
- (id,log) VALUES (?, ?'), [e_id, e_log];
- });
這裡的 e_id 和 e_log 是外部變量,executeSql 會映射數組參數中的每個條目給 "?"。
讀取操作
要讀取已經存在的記錄,我們可以使用回調來捕獲結果,如下所示:
JavaScript Code復制內容到剪貼板
- var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024);
- db.transaction(function (tx) {
- tx.executeSql('CREATE TABLE IF NOT EXISTS LOGS (id unique, log)');
- tx.executeSql('INSERT INTO LOGS (id, log) VALUES (1, "foobar")');
- tx.executeSql('INSERT INTO LOGS (id, log) VALUES (2, "logmsg")');
- });
- db.transaction(function (tx) {
- tx.executeSql('SELECT * FROM LOGS', [], function (tx, results) {
- var len = results.rows.length, i;
- msg = "<p>Found rows: " + len + "</p>";
- document.querySelector('#status').innerHtml += msg;
- for (i = 0; i < len; i++){
- alert(results.rows.item(i).log );
- }
- }, null);
- });
最終示例
最後,然我們把這個例子放到如下所示的完整 Html5 文檔中,然後嘗試在 Safari 浏覽器中運行它:
JavaScript Code復制內容到剪貼板
- <!DOCTYPE Html>
- <Html>
- <head>
- <script type="text/Javascript">
- var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024);
- var msg;
- db.transaction(function (tx) {
- tx.executeSql('CREATE TABLE IF NOT EXISTS LOGS (id unique, log)');
- tx.executeSql('INSERT INTO LOGS (id, log) VALUES (1, "foobar")');
- tx.executeSql('INSERT INTO LOGS (id, log) VALUES (2, "logmsg")');
- msg = '<p>Log message created and row inserted.</p>';
- document.querySelector('#status').innerHtml = msg;
- });
-
- db.transaction(function (tx) {
- tx.executeSql('SELECT * FROM LOGS', [], function (tx, results) {
- var len = results.rows.length, i;
- msg = "<p>Found rows: " + len + "</p>";
- document.querySelector('#status').innerHtml += msg;
- for (i = 0; i < len; i++){
- msg = "<p><b>" + results.rows.item(i).log + "</b></p>";
- document.querySelector('#status').innerHtml += msg;
- }
- }, null);
- });
- </script>
- </head>
- <body>
- <div id="status" name="status">Status Message</div>
- </body>
- </Html>
在浏覽器中這會生成如下所示結果:
復制代碼代碼如下:
Log message created and row inserted.</p><p>Found rows: 2</p><p>foobar</p><p>logmsg