HTML(三)——本地存儲

 1、本地存儲

本地存儲可分爲4類

Local Storage :永久存儲:數據將保持在硬盤中,即便瀏覽器被關閉了,該數據仍然存在,
下次打開瀏覽器訪問該網站時仍然能夠繼續使用 
Session Storage :臨時存儲:數據會隨着瀏覽器的關閉而消失。 
Indexed Database:NOSql,至關於一個key和value的集合,實現了NOSql的存儲方式 
Web SQL Database:實現了傳統的基於sql語句的數據庫操做,關係數據庫 javascript

一、提交表單發送到服務器的信息

1)、帶name的可用表單元素css

2)、urlhtml

3)、客戶端請求頭部信息java

4)、cookiejquery

二、客戶端本地存儲概要

顧名思義客戶端本地存儲就是將信息存儲在客戶端電腦上,cookie就是一種典型的傳統客戶端存儲,長期以來本地存儲能力一直是桌面應用區別於Web應用的一個主要優點,做爲Web應用程序而言,新一代的HTML標準對數據的本地存儲提出了更高的要求。傳統的Web數據存儲方式一直來使用的是Cookie,但Cookie有如下缺陷:git

a)、cookie會被附加在每一個HTTP請求中,因此無形中增長了流量。github

b)、因爲在HTTP請求中的cookie是明文傳遞的,因此安全性成問題。sql

c)、Cookie的大小限制在4 KB左右,容量達不到要求。chrome

HTML5中的Web Storage,稱爲Web本地存儲,在Web客戶端儲存數據的功能,用鍵值對的形式保存數據,曾經屬於HTML5的規範,目前已經被獨立出來造成單獨的規範體系。本地存儲優點:數據庫

a)、統一的標準,兼容性高(IE八、各大瀏覽器支持)

b)、數據存儲量大

c)、無需安裝插件

d)、減小網絡流量

e)、更加適合移動端

HTML5 提供了四種在客戶端存儲數據的新方法,即localStorage 、sessionStorage、globalStorage、Web Sql Database。 前面三個適用於存儲較少的數據,而Web Sql Database適用於存儲大型的,複雜的數據,我習慣把前面的三個稱之爲小存儲。 IE八、Firefox3.六、Chrome五、Safari四、Opera10,事實證實各個瀏覽器在API方面的實現基本上一致,存在必定的兼容性問題,但不影響正常使用。

 

在chrome瀏覽器中可使用開發者工具查看到各類不一樣的本地存儲方式,以下圖所示:

Web SQL Database 和 Indexed Database 都是在客戶端存儲大量結構化數據的解決方案。Web SQL Database 實現了傳統的基於 SQL 語句的數據庫操做,而 Indexed Database 實現了 NoSQL 的存儲方式。

Web Storage 這種用於存儲 (key, value),通常二者都是字符串;

IndexDB 是加強型的 Web Storage,也是存儲 (key, value);

Web SQL 則是 SQLite,一個完整的關係型數據庫,能夠執行 SQL。

WebSQL是SQLite在瀏覽器中的實現,因此它是一種關係型數據庫。因爲W3C對其規範定義不夠理想,各家瀏覽器有各自實現,有瀏覽器兼容問題;

IndexDB是一種key-value類型的非關係數據庫(NoSQL)

 

三、客戶端操做Cookies

1.3.一、得到操做cookies的庫

https://github.com/js-cookie/js-cookie

 

1.3.二、操做cookies

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Cookie</title>
    </head>
    <body>
        <input type="button" name="add" id="add" value="添加" />
        <input type="button" name="get" id="get" value="讀取" />
        <input type="button" name="remove" id="remove" value="清除" />
        
        <script src="js/js.cookie-2.1.3.min.js" type="text/javascript" charset="utf-8"></script>
        <script src="../js/jquery-1.11.3.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            $("#add").click(function(){
                Cookies.set('name','小明',{expires:7});
            })
            
            $("#get").click(function(){
                alert(Cookies.get('name'))
            })
            
            $("#remove").click(function(){
                Cookies.remove('name')
            })
        </script>
    </body>
</html>
View Code

 

 結果:

 

 添加的結果:

 

 

 讀取的結果:

 

 清除的結果:

 

 

四、localStorage

說明:將數據保存在客戶端本地的硬件設備(一般指硬盤,但也能夠是其餘硬件設備)中,即便瀏覽器被關閉了,該數據仍然存在,下次打開瀏覽器訪問網站時仍然能夠繼續使用。

操做localStorage

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>本地永久存儲:localStorage</title>
    </head>
    <body>
        <input type="button" value="添加" onclick="add()"/>
        <input type="button" value="讀取" onclick="get()"/>
        <input type="button" value="刪除" onclick="del()"/>
        
        <script type="text/javascript">
            
            //添加
            function add(){
                
                //方法一
                localStorage.setItem("name1","張三");
                
                localStorage.setItem("1","張三1");
                //方法二
                localStorage["name2"]="李四";
                //方法三
                localStorage.name3="王五";
                
                //存儲對象
                var str={name:"趙六",age:18}
                //序列化:把對象轉換爲String(由於JSON只能存儲String)
                localStorage.str=JSON.stringify(str);
            }
            
            //讀取
            function get(){
                //方法一
                console.log(localStorage.getItem("name1"));
                //方法二
                console.log(localStorage["name2"]);
                //方法三
                console.log(localStorage.name3);
                
                //讀取對象
                //反序列化
                var str=JSON.parse(localStorage.str)
                console.log(str.name);
                console.log(str.age);
                console.log(str);
            }
            
            //刪除
            function del(){
                //根據Key值刪除
                localStorage.removeItem("name")
                //刪除全部
                localStorage.clear();
            }
        </script>
    </body>
</html>
View Code

 

結果:

 

添加的結果:

 

 讀取的結果:

移除的結果:

 

 

 

五、sessionStorage

將數據臨時保存在客戶端session對象中。session對象就是會話對象,session中存儲的數據獨立於每一個客戶,該數據會隨着瀏覽器的關閉而消失。

sessionStorage的操做api與localStorage基本同樣,在不手動清除的狀況下localStorage永久保存,而sessionStorage只是臨時暫存。

sessionStorage使用

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>本地臨時存儲:sessionStorage</title>
    </head>
    <body>
        <input type="button" value="添加" onclick="add()"/>
        <input type="button" value="讀取" onclick="get()"/>
        <input type="button" value="刪除" onclick="del()"/>
        
        <script type="text/javascript">
            
            //添加
            function add(){
                
                //方法一
                sessionStorage.setItem("name1","張三");
                
                sessionStorage.setItem("1","張三1");
                //方法二
                sessionStorage["name2"]="李四";
                //方法三
                sessionStorage.name3="王五";
                
                //存儲對象
                var str={name:"趙六",age:18}
                //序列化:把對象轉換爲String(由於JSON只能存儲String)
                sessionStorage.str=JSON.stringify(str);
            }
            
            //讀取
            function get(){
                //方法一
                console.log(sessionStorage.getItem("name1"));
                //方法二
                console.log(sessionStorage["name2"]);
                //方法三
                console.log(sessionStorage.name3);
                
                //讀取對象
                //反序列化
                var str=JSON.parse(sessionStorage.str)
                console.log(str.name);
                console.log(str.age);
                console.log(str);
            }
            
            //刪除
            function del(){
                //根據Key值刪除
                sessionStorage.removeItem("name")
                //刪除全部
                sessionStorage.clear();
            }
        </script>
    </body>
</html>
View Code

 

結果:

添加的結果:

 

 讀取的結果:

 

 刪除的結果:

 

Web本地存儲事件監聽 

當程序修改localStorage與sessionStorage時將觸發全局事件。

當setItem(),removeItem()或者clear() 方法被調用,而且數據真的發生了改變時,就會觸發storage事件,若是須要進行監聽數據處理,經過如下方法:
window.addEventListener(event,handleEvent, capture)
event:設置成storage
handleEvent:事件處理函數
capture:事件處理順序,通常設置成false,表示採用冒泡方式處理

handleEvent處理事件的函數會接收到一個StorageEvent對象,該對象有如下屬性:
key:被修改的鍵。
oldValue:修改前的值(若是是增長新的鍵值,則該屬性爲null)
newValue:修改後的值(若是是刪除鍵值,則該屬性爲null)
url/uri:觸發當前存儲事件的頁面的url

注意:storage改變的時候,觸發這個事件會調用全部同域下其餘窗口的storage事件,不過它自己觸發storage即當前窗口是不會觸發這個事件的(固然ie這個特例除外,它包含本身本事也會觸發storage事件)

 

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>得到localStorage的值</title>
    </head>
    <body>
        <script type="text/javascript">
            console.log(localStorage.price);
            
            window.addEventListener("storage",function(obj){
                alert(obj.oldValue+","+obj.newValue+","+obj.url);
            },true);
        </script>
    </body>
</html>
View Code

 

運行結果以下:

3.三、cookie、sessionStorage、localStorage比較

 

 

六、Web SQL Database 

Web SQL Database可讓開發人員使用SQL語句操做客戶端瀏覽器中嵌入的SQLite數據庫 ,給開發人員提供了方便。對於簡單的數據,使用sessionStorage和localStorage可以很好地完成存取,可是對於處理複雜的關係型數據,它就力不從心了。這也是 HTML 5 的「Web SQLDatabase」API 接口的應用所在。我把它理解成一個Html5環境下能夠用Js執行CRUD的Web數據庫

三個核心方法
openDatabase:這個方法使用現有數據庫或建立新數據庫建立數據庫對象。
transaction:這個方法容許咱們根據狀況控制事務提交或回滾。
executeSql:這個方法用於執行真實的SQL查詢。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>商品信息</title>
        <style type="text/css">
            #div{
                width: 700px;
                height: 500px;
                margin:50px auto;
                border: 1px solid #4169E1;
                background-color: #FFFFFF;
            }
            #tab{
                border-collapse: collapse;
                border-color: aquamarine;
            }
            #tab th{
                width: 200px;
                text-align: center;
            }
            #fie{
                position: relative;
                top: 50px;
                border-radius: 30px;
            }
            #tables,#deltable{
                position: relative;
                top: 85px;
            }
            body{
                background-color: #CCCCCC;
            }
        </style>
    </head>
    <body>
        <div id="div">
            <input type="button" name="tables" id="tables" value="建立表" />
            <input type="button" name="deltable" id="deltable" value="刪除表" />
            
            <table border="1" id="tab">
                <caption><h1>商品信息</h1></caption>
                <tr>
                    <th>編號</th>
                    <th>名稱</th>
                    <th>價格</th>
                    <th>操做</th>
                </tr>
            </table>
            
            <fieldset id="fie">
                <legend>商品操做</legend>
                <p>
                    <label for="name">商品名稱:</label>
                    <input type="text" name="name" id="name" value="" />
                </p>
                <p>
                    <label for="price">商品價格:</label>
                    <input type="text" name="price" id="price" value="" />
                </p>
                <input type="button" name="add" id="add" value="添加" />
                <input type="button" name="alter" id="alter" value="修改" />
            </fieldset>
        
        </div>
    </body>
    
    <script src="../js/jquery-1.11.3.js" type="text/javascript" charset="utf-8"></script>
    <script type="text/javascript">
        
        //頁面加載時調用
        $(function(){
            databa()    //建立/打開數據庫
            sel()        //讀取數據庫
        })
        
        //獲取數據庫對象
        var db;
        //建立/打開數據庫
        function databa(){
            //(建立名稱爲commodity,版本爲1.0,描述爲產品數據庫,3M大小的數據庫,回調函數)
            db=openDatabase("commodity",1.0,"商品數據庫",1024*1024*3,function(){
                alert("數據庫建立/打開成功!!!")    
            })
        }
        
        //建立表
        $("#tables").click(function(){
            //數據庫對象.transaction(function(tx){tx.executeSql(sql語句,[?值],成功時的回調函數,失敗時的回調函數)})
            db.transaction(function(tx){
                tx.executeSql("create table if not exists physics"
                                +"("
                                +"   id integer primary key autoincrement,"
                                +"   name text not null,"
                                +"   price double"
                                +")"
                ,[]
                ,function(tx,result){
                    alert("建立成功")
                }
                ,function(tx,error){
                    alert("建立失敗")
                }
                )
            });
        })
        
        //刪除表
        $("#deltable").click(function(){
            db.transaction(function(tx){
                tx.executeSql(
                    "drop table physics"
                    ,[]
                    ,function(tx,result){
                        alert("刪除成功!!!")
                    }
                    ,function(tx,error){
                        alert("刪除失敗!!!")
                    }
                )
            })
        })
        
        //添加數據
        $("#add").click(function(){
                db.transaction(function(tx) {
                    tx.executeSql(
                        "insert into physics(name,price) values(?,?)", 
                        [$("#name").val(),$("#price").val()],
                        function(tx, result) {
                            alert("添加數據成功")
                            sel()
                        },
                        function(tx, error) {
                            alert('添加數據失敗' + error.message);
                        });
                });
        })
        
        //讀取數據
        function sel(){
                //將表格中tr索引大於0的元素刪除
                $("#tab tr:gt(0)").remove();
                db.transaction(function(tx) {
                    tx.executeSql(
                        "select id,name,price from physics", [],
                        function(tx, result) {
                            $.each(result.rows, function(i,obj) {
                                var tr=$("<tr/>");
                                $("<td/>").text(obj["id"]).appendTo(tr);
                                $("<td/>").text(obj["name"]).appendTo(tr);
                                $("<td/>").text(obj["price"]).appendTo(tr);
                                var del=$("<input type='button' value='刪除' onclick='dels("+obj["id"]+")' />")
                                var up=$("<input type='button' value='編輯'  onclick='up("+obj["id"]+")'/>")
                                $("<td/>").append(del).append(up).appendTo(tr);
                                tr.appendTo("#tab");
                                
                            });
                        },
                        function(tx, error) {
                            
                        });
                });
        }
        
        //修改:獲取原數據
        var bh="";
        function up(id){
            bh=id;
            db.transaction(function(tx){
                tx.executeSql(
                    "select name,price from physics where id=?"
                    ,[id]
                    ,function(tx,result){
                        $.each(result.rows, function(i,obj) {
                            $("#name").val(obj["name"]);
                            $("#price").val(obj["price"]);
                        });
                    }
                    ,function(tx,error){
                        
                    }
                    
                )
            })
        }
        
        //修改
        $("#alter").click(function(){
            db.transaction(function(tx){
                tx.executeSql(
                    "update physics set name=?,price=?  where id=?"
                    ,[$("#name").val(),$("#price").val(),bh]
                    ,function(tx,recult){
                        alert("修改爲功!!!")
                        sel()
                    }
                    ,function(tx,error){
                        alert("修改失敗!!!")
                    }
                )
            })
        })
        
        //刪除數據
        function dels(id){
            db.transaction(function(tx){
                tx.executeSql("delete from physics where id=?"
                ,[id]
                ,function(tx,result){
                    alert("刪除成功!!!")
                    sel()
                }
                ,function(tx,error){
                    alert("刪除失敗!!!")
                })
            
            })
        }
        
        
    </script>
</html>

 

 

七、IndexedDB

一、ndexedDB因爲受到W3C的推崇。瀏覽器廠商的實現狀況要好一些。但因爲目前規範說明書還只是處於候選建議階段。各大瀏覽器廠商目前的實現還有一些差別化。

IndexedDB是在瀏覽器中保存結構化數據的一種數據庫,爲了替換WebSQL(標準已廢棄,但被普遍支持)而出現。IndexedDB使用NoSQL的形式來操做數據庫,保存和讀取是JavaScript對象,同時還支持查詢及搜索。

IndexedDB保存的是對象,而不是使用表保存數據。打開數據庫使用indexDB.open方法,這方法有兩個參數,第一個是數據庫名稱,第二個是數據版本號。

IndexedDB的操做徹底是異步進行的,每一次IndexedDB操做,都須要註冊onerror或onsuccess事件處理程序。

 

二、對象存儲空間(ObjectStore)

對象存儲空間(ObjectStore)能夠想象成關係數據庫的表,在初始化DB觸發onupgradeneeded時,建立ObjectStore。使用createObjectStore方法,第一個參數是對象名,第二個參數是對象屬性,通常是設置keyPath(做爲鍵使用)。

由於對新數據的操做都須要在transaction中進行,而transaction又要求指定object store,因此咱們只能在建立數據庫的時候初始化object store以供後面使用,這正是onupgradeneeded的一個重要做用

有了數據庫後咱們天然但願建立一個表用來存儲數據,但indexedDB中沒有表的概念,而是objectStore,一個數據庫中能夠包含多個objectStore,objectStore是一個靈活的數據結構,能夠存放多種類型數據。也就是說一個objectStore至關於一張表,裏面存儲的每條數據和一個鍵相關聯。

咱們可使用每條記錄中的某個指定字段做爲鍵值(keyPath),也可使用自動生成的遞增數字做爲鍵值(keyGenerator),也能夠不指定。選擇鍵的類型不一樣,objectStore能夠存儲的數據結構也有差別

不使用—>任意值,可是沒添加一條數據的時候須要指定鍵參數

keyPath—>Javascript對象,對象必須有一屬性做爲鍵值

keyGenerator—>任意值(db.createObjectStore('students',{autoIncrement: true});)

都使用—>Javascript對象,若是對象中有keyPath指定的屬性則不生成新的鍵值,若是沒有自動生成遞增鍵值,填充keyPath指定屬性

三、事務

全部讀取或修改數據的操做,都要經過事務來完成。建立事務使用transaction方法,第一個參數是須要訪問的ObjectStore,第二個參數是訪問模式(readwrite可讀可寫、readonly只讀,默認是隻讀)。

四、遊標查詢

使用事務能夠直接經過鍵檢索單個對象,而須要檢索多個對象時候就須要使用遊標。遊標是指向結果集的指針,不提早收集結果。遊標指針會先指向結果中的第一項,在接到查找下一項指令時,纔會指向下一項。

這裏有幾點要注意:

1. 若是須要修改或刪除數據,就須要打開成讀寫模式。

2. cursor的非空校驗是必要的。

3. 修改或刪除的操做也是有onsuccess和onerror的,只是在示例中沒有寫出來。

4. 調用continue纔會移動到下一項

另外能夠設置遊標的鍵範圍和遊標的方向,即打開openCursor方法時能夠傳這兩個參數(openCursor(鍵範圍,方向)),第一個參數是object類型,第二個參數是字符串類型。

遊標鍵範圍

鍵範圍由IDBKeyRange的實例表示。

IDBKeyRange.only('001');           //只想要鍵爲001的結果
IDBKeyRange.lowerBound('002');        //從鍵爲002開始,到最後
IDBKeyRange.lowerBound('002', true);     //從鍵爲002開始,但忽略002,到最後
IDBKeyRange.upperBound('002');        //從頭開始,到鍵爲002爲止
IDBKeyRange.upperBound('002', true);     //從頭開始,到鍵爲002爲止,但忽略002
IDBKeyRange.bound('001', '005');        //從001開始,到爲005爲止
IDBKeyRange.bound('001', '005', true, true);   //從001開始,到爲005爲止,但忽略00一、005

遊標方向

next : 從第一項到最後一項(默認)

prev : 從最後一項到第一項

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>IndexedDb:商品信息</title>
        <style type="text/css">
            #div{
                width: 700px;
                height: 500px;
                margin:50px auto;
                border: 1px solid #4169E1;
                background-color: #FFFFFF;
                
            }
            #tab{
                border-collapse: collapse;
                border-color: aquamarine;
            }
            #tab th{
                width: 200px;
                text-align: center;
            }
            #fie{
                position: relative;
                top: 50px;
                border-radius: 30px;
            }
            #tables,#deltable{
                position: relative;
                top: 85px;
            }
        </style>
    </head>
    <body>
        
        <div id="div">
            <table border="1" id="tab">
                <caption><h1>商品信息</h1></caption>
                <tr>
                    <th>編號</th>
                    <th>名稱</th>
                    <th>價格</th>
                    <th>操做</th>
                </tr>
            </table>
            
            <fieldset id="fie">
                <legend>商品操做</legend>
                <p>
                    <label for="name">商品編號:</label>
                    <input type="text" name="id" id="id" value="" />
                </p>
                <p>
                    <label for="name">商品名稱:</label>
                    <input type="text" name="name" id="name" value="" />
                </p>
                <p>
                    <label for="price">商品價格:</label>
                    <input type="text" name="price" id="price" value="" />
                </p>
                <input type="button" name="add" id="add" value="添加" />
                <input type="button" name="alter" id="alter" value="修改" />
            </fieldset>
        </div>
        
        <script src="../js/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            
            $(function(){
                databas();
            })
            
            var db;
            //建立數據庫、建立表
            function databas(){
                //建立一個名爲commodity,版本爲2的數據庫
                var requst=indexedDB.open("commodity",2);
                //綁定成功時的回調函數
                requst.onsuccess=function(e){
                    db=e.target.result;
                    console.log("建立數據庫成功!!!");
                    get()
                }
                //綁定失敗時的回調函數
                requst.onerror=function(e){
                    console.log("錯誤:"+e.target.errorCode || e.target.error)
                };
                
                //建立表
                requst.onupgradeneeded =function(e){
                    e.target.result.createObjectStore("commoditys",{"keyPath":"id"})
                    console.log("建立表成功")
                }
            }
            
            //讀取數據
            function get(){
                $("#id").val("")
                $("#name").val("")
                $("#price").val("")
                $("#tab tr:gt(0)").remove();
                var request=db.transaction("commoditys","readonly").objectStore("commoditys").openCursor();
                request.onsuccess=function(e){
                    var cursor =e.target.result;
                    if(cursor){
                        var obj=cursor.value;
                        var tr=$("<tr/>")
                        $("<td/>").text(obj.id).appendTo(tr);
                        $("<td/>").text(obj.name).appendTo(tr);
                        $("<td/>").text(obj.price).appendTo(tr);
                        var del=$("<input type='button' value='刪除' id='del' onclick='del(this,"+obj.id+")'>");
                        var up=$("<input type='button' value='編輯' id='up' onclick='up(this,"+obj.id+")'>");
                        $("<td/>").append(del).append(up).appendTo(tr);
                        tr.appendTo($("#tab"));
                        cursor.continue()
                    }
                    
                }
            }
            
            function text(){
                return {
                    id:$("#id").val(),
                    name:$("#name").val(),
                    price:$("#price").val()
                }
            }
            
            //添加數據
            $("#add").click(function(){
                var tx=db.transaction("commoditys","readwrite").objectStore("commoditys").add(text());
                get()
                alert("添加成功")
            })
            
            //獲取要修改數據
            function up(t,id){
                var request=db.transaction("commoditys","readonly").objectStore("commoditys").openCursor(""+id+"");
                request.onsuccess=function(e){
                    var cursor =e.target.result;
                    if (cursor) {
                        var obj=cursor.value;
                        $("#id").val(obj.id);
                        $("#name").val(obj.name);
                        $("#price").val(obj.price);
                    }
                }
            }
            //修改數據
            $("#alter").click(function(){
                var requset=db.transaction("commoditys","readwrite").objectStore("commoditys").put(text());
                requset.onsuccess=function(e){
                    console.log("修改爲功")
                    get()
                }
            })
            
            //刪除數據
            function del(t,id){
                if(confirm("您肯定要刪除嗎?")){
                    var requset=db.transaction("commoditys","readwrite").objectStore("commoditys").delete(""+id+"");
                    requset.onsuccess=function(e){
                        alert("刪除成功!!!")
                        get()
                    }
                    requset.onerror=function(e){
                        alert("刪除失敗")
                    }
                }
            }
            
        </script>
    </body>
</html>
相關文章
相關標籤/搜索