• HTML(三)——本地存储


     一、本地存储

    本地存储可分为4类

    Local Storage :永久存储:数据将保持在硬盘中,即使浏览器被关闭了,该数据仍然存在,
    下次打开浏览器访问该网站时仍然可以继续使用 
    Session Storage :临时存储:数据会随着浏览器的关闭而消失。 
    Indexed Database:NOSql,相当于一个key和value的集合,实现了NOSql的存储方式 
    Web SQL Database:实现了传统的基于sql语句的数据库操作,关系数据库 

    1、提交表单发送到服务器的信息

    1)、带name的可用表单元素

    2)、url

    3)、客户端请求头部信息

    4)、cookie

    2、客户端本地存储概要

    顾名思义客户端本地存储就是将信息存储在客户端电脑上,cookie就是一种典型的传统客户端存储,长期以来本地存储能力一直是桌面应用区别于Web应用的一个主要优势,作为Web应用程序而言,新一代的HTML标准对数据的本地存储提出了更高的要求。传统的Web数据存储方式一直来使用的是Cookie,但Cookie有以下缺陷:

    a)、cookie会被附加在每个HTTP请求中,所以无形中增加了流量。

    b)、由于在HTTP请求中的cookie是明文传递的,所以安全性成问题。

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

    HTML5中的Web Storage,称为Web本地存储,在Web客户端储存数据的功能,用键值对的形式保存数据,曾经属于HTML5的规范,目前已经被独立出来形成单独的规范体系。本地存储优势:

    a)、统一的标准,兼容性高(IE8、各大浏览器支持)

    b)、数据存储量大

    c)、无需安装插件

    d)、减少网络流量

    e)、更加适合移动端

    HTML5 提供了四种在客户端存储数据的新方法,即localStorage 、sessionStorage、globalStorage、Web Sql Database。 前面三个适用于存储较少的数据,而Web Sql Database适用于存储大型的,复杂的数据,我习惯把前面的三个称之为小存储。 IE8、Firefox3.6、Chrome5、Safari4、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)

    3、客户端操作Cookies

    1.3.1、获得操作cookies的库

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

    1.3.2、操作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

     结果:

     添加的结果:

     

     读取的结果:

     清除的结果:

    4、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

    结果:

    添加的结果:

     读取的结果:

    移除的结果:

    5、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.3、cookie、sessionStorage、localStorage比较

     

    6、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{
                     700px;
                    height: 500px;
                    margin:50px auto;
                    border: 1px solid #4169E1;
                    background-color: #FFFFFF;
                }
                #tab{
                    border-collapse: collapse;
                    border-color: aquamarine;
                }
                #tab th{
                     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>

    7、IndexedDB

    1、ndexedDB由于受到W3C的推崇。浏览器厂商的实现情况要好一些。但由于目前规范说明书还只是处于候选建议阶段。各大浏览器厂商目前的实现还有一些差异化。

    IndexedDB是在浏览器中保存结构化数据的一种数据库,为了替换WebSQL(标准已废弃,但被广泛支持)而出现。IndexedDB使用NoSQL的形式来操作数据库,保存和读取是JavaScript对象,同时还支持查询及搜索。

    IndexedDB保存的是对象,而不是使用表保存数据。打开数据库使用indexDB.open方法,这方法有两个参数,第一个是数据库名称,第二个是数据版本号。

    IndexedDB的操作完全是异步进行的,每一次IndexedDB操作,都需要注册onerror或onsuccess事件处理程序。

     

    2、对象存储空间(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指定属性

    3、事务

    所有读取或修改数据的操作,都要通过事务来完成。创建事务使用transaction方法,第一个参数是需要访问的ObjectStore,第二个参数是访问模式(readwrite可读可写、readonly只读,默认是只读)。

    4、游标查询

    使用事务可以直接通过键检索单个对象,而需要检索多个对象时候就需要使用游标。游标是指向结果集的指针,不提前收集结果。游标指针会先指向结果中的第一项,在接到查找下一项指令时,才会指向下一项。

    这里有几点要注意:

    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为止,但忽略001、005

    游标方向

    next : 从第一项到最后一项(默认)

    prev : 从最后一项到第一项

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title>IndexedDb:商品信息</title>
            <style type="text/css">
                #div{
                     700px;
                    height: 500px;
                    margin:50px auto;
                    border: 1px solid #4169E1;
                    background-color: #FFFFFF;
                    
                }
                #tab{
                    border-collapse: collapse;
                    border-color: aquamarine;
                }
                #tab th{
                     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>
  • 相关阅读:
    在实践中不断总结和提升
    [转]态度的魔力 Net
    回答的智慧 Net
    [转] 【领导必读】唐僧为什么可以领导孙悟空 Net
    [转载]人生感悟:8个笑话 8味人生 Net
    人生成功的十大说话技巧 Net
    最新人生感悟语句摘选 Net
    2012注定是收获的一年,奋斗才刚刚开始
    程序员职业发展的绊脚石思想的枷锁
    AgileEAS.NET5.0界面设计器使用说明书(上)
  • 原文地址:https://www.cnblogs.com/huoqin/p/9458082.html
Copyright © 2020-2023  润新知