客戶端本地儲存的比較及使用window.name資料傳輸

龍恩0707發表於2015-01-10

一: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資料已經拿到了的話,以後不需要的話,我們可以銷燬掉,清空等操作。

相關文章