代码改变世界

客户端本地存储的比较及使用window.name数据传输

2015-01-10 15:16  龙恩0707  阅读(2490)  评论(0编辑  收藏  举报

一:cookie:

 1. 什么是cookie?

     Cookie是在客户端用于存储会话信息的,用户请求页面在web服务器与浏览器之间传递。每当同一台计算机通过浏览器请求某个页面时,就会发送这个 cookie。

 2. cookie的限制?

     1. Cookie的数据大小限制只能为4kb数据,如果数据长度超过4kb数据,超过后的数据将返回空字符串。

     2. Cookie是以文件形式存储在客户端计算机中,查看和修改cookie很方便,但是安全性方面不好,因此重要的数据不要使用cookie来存储。

     3. Cookie是有 有效期概念的,如果想要cookie存储多长时间,可以设置cookie的时间,一般的情况下,cookie的生命周期是在游览器关闭的时候失效。

     4. Cookie是有域的概念的,在不同的域下,cookie不能互相使用,cookie对于那个域是有效的,所有向该域发送的请求中都会包含这个cookie 的信息的,这个值可以包含子域(subdomain 如www.zuixiandao.cn) ,也可以不包含它(如.zuixiandao.cn, 对于所有的zuixiandao.cn的所有子域都有效). 如果没有明确的指定,那么这个域会被认作来自设置cookie的那个域。

     5. Cookie路径的概念:对于指定域中的那个路径,应该向服务器发送cookie,比如我们可以指定cookie只有从http://www.zuixiandao.cn/books/中才能访问,那么http://www.zuixiandao.cn的页面就不会发送cookie信息。

     6. Cookie失效时间的概念:表示cookie何时应该被删除,默认情况下,浏览器会话结束时即将删除所有的cookie,不过也可以自己设置删除时间的。这个值是个GMT格式的日期(Wdy DD-Mon-YYYY HH:MM:SS GMT),用于指定应该删除cookie的准确时间,因此,cookie可在浏览器关闭后依然保存在用户的机器上(同一个浏览器,不同的浏览器不能保存),如果设置的日期是过期的日期,那么cookie立刻删掉。

      7. Cookie安全标志 指定后,cookie只有在使用SSL连接的时候才发送到服务器。比如:cookie信息只能发送给https://www.zuixiandao.cn, 而http://www.zuixiandao.cn的请求则不能发送cookie

二: javascript中的cookie

  1. Javascript中的cookie是 一系列由分号隔开的名-值对,如下面的淘宝的cookie,如下:

         document.cookie = "isg=E5AA5F2CEE8AA93BB351D1601F7B218E; thw=cn; _med=dw:1920&dh:1080&pw:1920&ph:1080&ist:0; v=0; t=1292efa78d867ff6275e6c5cb971bed7";

     2. 设置cookie的超时。

         expires;   // 设置cookie的过期的时间

         以下设置 cookie 在 365天后超时;

         var date = new Date();

         date.setTime(date.getTime()+365*24*3600*1000);

         document.cookie = ‘key:value;expires =' + date.toGMTString();

下面是设置cookie, 删除cookie,及 获取cookie的封装代码如下:

// 获取所有的cookies
function getCookies() {
    var allCookies = document.cookie;
    return decodeURIComponent(allCookies);
}
// 获取指定的cookie
function getOneCookie(name) {
    var allCookies = document.cookie.split(";");
    for(var i = 0, ilen = allCookies.length; i < ilen; i++) {
        var temp = allCookies[i].split("=");
        if($.trim(decodeURIComponent(temp[0])) == name) {
            return decodeURIComponent(temp[1]);
         }
    }
    return -1;
}
// 添加cookie 有效期是一年
function addCookie(name,value,expires,path,domain,secure) {
    var curCookie = encodeURIComponent(name) + '=' + encodeURIComponent(value);
    if(expires instanceof Date) {
        curCookie += ';expires =' + expires.toGMTString();
    }else {
        var date = new Date();                
date.setTime(date.getTime()+365*24*3600*1000); curCookie += ';expires =' + date.toGMTString(); } if(path) { curCookie += "; path=" + path; } if(domain) { curCookie += "; domain=" +domain; } if(secure) { curCookie += "; secure"; } document.cookie = curCookie; } // 删除cookie function removeCookie(name,path,domain,secure) { addCookie(name,"",new Date(0),path,domain,secure); }

Demo实践:

     下面我们来做一个小需求,比如一个登陆页面,有 有户名,密码,记住密码,及显示cookie和删除cookie按钮。当我点击记住密码的时候,那么当我第重启开页面时候,只要输入用户名,密码会自动填充,当然我们也可以点击删除cookie按钮进行删除,如下代码:

HTML代码:

<h2>cookie介绍</h2>
<p>
    <label>用户名:</label>
    <input type="text" class="userName" id="userName"/>
</p>
<p>
    <label>密码:</label>
    <input type="password" id="password">
</p>
<p>
    <label>记住密码:</label>
    <input type="checkbox" id="remember"/>
</p>
<input value="删除" type="button" id="delCookie">  
<input type="button" value="显示cookie" id="showpassword">

JS代码如下:

<script>
        // 获取所有的cookies
        function getCookies() {
            var allCookies = document.cookie;
            return allCookies;
        }
        // 获取指定的cookie
        function getOneCookie(name) {
            var allCookies = document.cookie.split(";");
            for(var i = 0, ilen = allCookies.length; i < ilen; i++) {
                var temp = allCookies[i].split("=");
                if(temp[0] == decodeURIComponent(name)) {
                    return decodeURIComponent(temp[1]);
                }
            }
            return -1;
        }
        // 添加cookie 有效期是一年
        function addCookie(name,value,expires,path,domain,secure) {
            var curCookie = encodeURIComponent(name) + '=' + encodeURIComponent(value);
            if(expires instanceof Date) {
                curCookie += ';expires =' + expires.toGMTString();
            }else {
                var date = new Date();
                date.setTime(date.getTime()+365*24*3600*1000);
                curCookie += ';expires =' + date.toGMTString();
            }
            if(path) {
                curCookie += "; path=" + path;
            }
            if(domain) {
                curCookie += "; domain=" +domain;
            }
            if(secure) {
                curCookie += "; secure";
            }
            document.cookie = curCookie;
        }
        // 删除cookie 
        function removeCookie(name,path,domain,secure) {
            addCookie(name,"",new Date(0),path,domain,secure);
        }
        
        $("#userName").unbind('blur').bind('blur',function(){
              var val = $(this).val();
              if(val) {
                 var curCookie = getOneCookie(val);
                 if(curCookie != -1) {
                    $("#password").val(curCookie);
                 }
              }
        });
        // 记住密码
        $("#remember").unbind('click').bind('click',function(){
            if(document.getElementById("remember").checked) {
                if($("#userName").val() && $("#password").val()) {
                    addCookie($("#userName").val(),$("#password").val());  
                    alert("Saved!");
                }
                  
            }
        });
        // 删除cookie
        $("#delCookie").unbind('click').bind('click',function() {
            if($("#userName").val()) {
                removeCookie($("#userName").val());
                alert(getCookies());
            }else {
                alert("用户名为空");
            }
        });

        // 显示cookie
        $("#showpassword").unbind('click').bind('click',function(){
            if($("#userName").val()) {
                var curCookie = getOneCookie($("#userName").val());
                if(curCookie != -1) {
                    alert(curCookie);
                }else {
                    alert("没有cookie");
                }
                
            }else {
                alert("没有cookie");
            } 
        });
    </script>

效果如下:

使用cookie的demo 点击我 进行查看效果;

三:IE用户数据;

    在IE5.0中,微软通过一个自定义行为引入了持久化用户数据的概念,用户数据允许每个文档最多128kb的数据,每个域名最多1MB的数据,要使用持久化数据,首先必须如下所示,使用css在某个元素上指定userData行为:

<div style="behavior:url(#default#userData)" id="dataStore">IE用户数据</div>

针对IE有如下使用方法:

1. getAttribute(“key”) 获取指定的属性值。

2. load(object) 从 userData 存储区载入存储的对象数据。

3. removeAttribute(“key”) 移除对象的指定属性。

4. save(object) 将对象数据存储到一个 userData 存储区。

5. setAttribute(“key”,”value”) 设置指定的属性值。

我们继续做一个demo来演示下在IE浏览器下的存储的demo。

HTML代码如下:

<div style="behavior:url(#default#userData)" id="dataStore">IE用户数据</div>

<
input value="IE下保存数据" type="button" id="IESave"> <input type="button" value="IE下获取数据" id="IEGet"> <input type="button" value="IE下删除数据" id="IERemove">

JS代码如下:

var dataStore = document.getElementById("dataStore");
$("#IESave").click(function(e){
    dataStore.setAttribute("name","tugenhua");
    dataStore.setAttribute("book",'111111');
    dataStore.save("bookInfo");
});
// IE下获取数据
$("#IEGet").click(function(){
    dataStore.load("bookInfo");
    alert(dataStore.getAttribute("name"));
    alert(dataStore.getAttribute("book"));
});

// IE下删除数据 
$("#IERemove").click(function(){
    dataStore.removeAttribute("name");
    dataStore.removeAttribute("book");
    dataStore.save("bookInfo");
});

IE浏览器下的demo如下:

 使用IE浏览器下查看效果 请点击我!!

四:sessionStorage 和 localStorage 

   Html5新增了两个本地存储数据,分别是sessionStorage 和 localStorage.

   浏览器支持程度如下:

   

注意:IE8 及 以上都支持 web storage。

   sessionStorage: 将数据保存在session对象中,所谓session,指用户浏览某个网站时,从进入网站到浏览器关闭的这段时间,也就是用户浏览这个网站所花费的时间。

        生命周期:指只在当前的窗口有效,打开一个新的同源窗口,或者说重启浏览器都失效。

        数据大小:可以保存5MB甚至更多。

   localStorage: 将数据保存在客户端本地的硬件设备(通常是指硬盘,但也可以是其他硬件设备),即使浏览器被关闭了,该数据依然存在,下次打开浏览器访问网站时仍然可以继续使用。但是,数据保存是按不同的浏览器分别进行的,也就是说,如果打开别的浏览器,是读取不到在这个浏览器中保存的数据的。

      生命周期:数据一直保存在硬盘中。持久性保存(但是不同的浏览器保存的数据,是不能通用的)。

     数据大小:可以保存5MB甚至更多的数据。

    1. cookie 与 sessionStorage 及 localStorage的区别;   

        共同点:都是在客户端存储数据,且是同源的。

    区别:

  1. 存储大小不一样;cookie存储数据最大只能为4kb,而sessionStorage与localStorage可以保存5MB甚至更多数据。
  2. Cookie数据始终在同源的http请求中携带,即cookie在浏览器与服务器之间来回传递,而sessionStorage与localStorage不会自动发给服务端,仅在本地保存。
  3. 数据有效期不同;sessionStorage仅在当前浏览器窗口未关闭之前有效(同源的新窗口不生效),localStorage仅在当前的浏览器下永久生效(不同的浏览器不能共享数据),不管关闭了 重新打开的 还是生效的。Cookie只在设置的cookie过期时间之前一直有效,即使窗口或者浏览器关闭,或者打开新的同源窗口。
  4. 作用域不同;sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面,localStorage在所有的同源窗口中都是共享的(只在相同的浏览器下),cookie在所有的同源窗口都是共享的(仅在同一个浏览器中)。

      SessionStorage与LocalStorage他们都拥有相同的方法;

      1. setItem存储value

         用法:.setItem( key, value),代码如下:

         localStorage.setItem(key,value):将value存储到key字段

      2. getItem获取value

          用法:.getItem(key) 代码如下:

          localStorage.getItem(key):获取指定key本地存储的值

      3. removeItem删除key

          用法:.removeItem(key),代码如下:

          localStorage.removeItem(key):删除指定key本地存储的值

      4. clear清除所有的key/value

          用法:.clear(),代码如下:

          localStorage.clear();  清除所有的数据(firefox除外)

      它将删除所有同源的本地存储的localStorage数据

      而对于Session Storage,它只清空当前会话存储的数据。

      sessionStorage也有上面一样的方法;

下面我们来使用sessionStorage及 localStorage 来练习下,来做个demo。如下:

HTML代码如下:

<h1>web Storage实列</h1>
<p id="msg"></p>
<input type="text" id="input" />
<input type="button" value="保存数据" id="saveData"/>
<input type="button" value="读取数据" id="readData"/>
<input type="button" value="删除数据" id="removeData"/>
<input type="button" value="清除所有的数据" id="clearData"/>

    页面上一个input输入框,当我点击 保存数据 按钮后 分别使用sessionStorage和localStorage 把值保存起来,当我点击 读取数据 按钮后 读取数据,分别在不同的浏览器或者新的同源窗口 或者关闭浏览器窗口 重新打开新窗口 来分别看看之间的区别,区别上面已经总结了,下面我们来看看JS代码如下

<script>
        // sessionStorage demo
        $("#saveData").unbind('click').bind('click',function(){
            var inputVal = $("#input").val();
            sessionStorage.setItem("message",inputVal);
            //localStorage.setItem("message",inputVal);
        });
        $("#readData").unbind("click").bind('click',function(){
            var msg = sessionStorage.getItem("message");
            //var msg = localStorage.getItem("message");
            $("#msg").html(msg);
        });
        $("#removeData").unbind('click').bind('click',function(){
            sessionStorage.removeItem("message");
            //localStorage.removeItem("message");
        });
        $("#clearData").unbind('click').bind('click',function(){
            sessionStorage.clear();
            //localStorage.clear();
        });
</script>

如上的代码,我们现在继续来看看效果如下:

使用sessionStorage效果请点击: 

使用localStorage效果请点击:

我们还可以做一点复杂的应用,比如如下一个表格有一些字段,比如姓名,email,tel,及备注字段,我们先保存到本地去,然后根据姓名这个字段进行搜索就可以搜索到数据到,我们可以称为这是简单的本地数据库,如下代码:

HTML:

<table>
    <tr>
        <td>姓名:</td>
        <td>
            <input type="text" id="name"/>
        </td>
    </tr>
    <tr>
        <td>EMALL:</td>
        <td>
            <input type="text" id="email"/>
        </td>
    </tr>
    <tr>
        <td>电话号码:</td>
        <td>
            <input type="text" id="tel"/>
        </td>
    </tr>
    <tr>
        <td>备注:</td>
        <td>
            <input type="text" id="memo"/>
        </td>
    </tr>
    <tr>
        <td>保存</td>
        <td>
           <input type="button" id="save" value="保存"/>
        </td>
    </tr>
</table>
     <p>
         检索:<input type="text" id="file"/>
         <input type="button" id="find" value="检索"/>
     </p>
     <p id="msg"></p>

JS代码如下:

//  保存数据
$("#save").unbind('click').bind('click',function(){
     var data = new Object;
     data.name = $("#name").val();
     data.email = $("#email").val();
     data.tel = $("#tel").val();
     data.memo = $("#memo").val();
     var str = JSON.stringify(data);
     localStorage.setItem(data.name,str);
     alert("数据已经保存");
 });

 // 检索数据
 $("#find").unbind('click').bind('click',function(){
      var find = $("#file").val();
      var str = localStorage.getItem(find);
      var data = JSON.parse(str);
      var result = "姓名:" + data.name + "</br>";
          result += "Email: " + data.email + "</br>";
          result += "tel:" + data.tel + "</br>";
          result += "备注:" + data.memo + "</br>";
      $("#msg").html(result);
  });

demo如下效果:

请点击查看:

五:window.name 实现跨域数据传输。

     Window.name 中的name值在不同的页面(甚至不同的域名)加载后依旧存在,并且数据量可以达到2MB。

     Window.name 数据传输的基本原理:

  1. 同域下:Name在浏览器环境中是一个全局/window对象的属性,且当在ifrmae中加载页面时,name的属性值依旧保持不变。

          比如我们在同域下abc.example.com下 有2个页面 app.html 和 data.html

          App.html页面代码嵌套一个iframe data.html页面,代码如下:

          <iframe src="http://abc.example.com/demo/tugenhua0707/storage/data.html" id="iframe"></iframe>

          其中data.html 页面 使用一个window.name = “111”;来保存数据。

      现在我们接下来在app.html页面 如何来调用同域下的data.html下的window.name的数据,首先我们先要获取到这个iframe,然后判断iframe是否加载完,加载完后就获取这个iframe中的window.name, 

     App.html JS的代码如下:

function iframeIsLoad(iframe,callback){
    if(iframe.attachEvent) {
       iframe.attachEvent('onload',function(){
            callback && callback();
        });
     }else {
         iframe.onload = function(){
             callback && callback();
         }
     }
 }
var iframe = document.getElementById("iframe");
// 同域下
iframeIsLoad(iframe,function(){
    var data = iframe.contentWindow.name;
        alert(data);
 });

     2. 跨域下:

        现在我们使用hosts文件来绑定2个IP 来演示下跨域的情况,在hosts文件绑定如下:

         127.0.0.1  abc.example.com  和 127.0.0.1 def.example.com

        我们现在在 abc.example.com 新建一个app.html页面 里面还是嵌套一个 def.example.com域下的 data.html页面,代码如下:

     App.html代码如下:

<iframe src="http://def.example.com/demo/tugenhua0707/storage/data.html" id="iframe"></iframe>

    如果我们还是和上面的方式取数据的话 明显报错跨域了,现在我们是使用window.name解决跨域下数据的传输,那么我们可以使用一个同域abc.example.com下的代理页面proxy.html来做处理,通过在def.example.com域下的data.html页面加载一个与abc.example.com同域下的proxy.html页面, 将该目标页面设置iframe的name属性,因为app.html 与 proxy.html是在同一个域下,所以我们可以获取到。

在app.html页面 JS代码如下:

function iframeIsLoad(iframe,callback){
    if(iframe.attachEvent) {
        iframe.attachEvent('onload',function(){
             callback && callback();
        });
    }else {
        iframe.onload = function(){
             callback && callback();
         }
     }
 }       
var iframe = document.getElementById("iframe");
var state = 0;
// 跨域下
iframeIsLoad(iframe,function(){ if (state === 1) { var data = iframe.contentWindow.name; // 读取数据 alert(data); //弹出111 } else if (state === 0) { state = 1; iframe.contentWindow.location = "http://abc.example.com/demo/tugenhua0707/storage/proxy.html"; // 设置的代理文件 } });

当然如上:我们如果name数据已经拿到了的话,以后不需要的话,我们可以销毁掉,清空等操作。