web客戶端存儲技術

cookie

cookie的優點可以與服務器共享狀態,每次經過ajax請求的時候都會將cookie附帶到請求的header,服務端可以直接讀取到本地存儲的數據。css

GET /sample_page.html HTTP/1.1
Host: www.example.org
Cookie: yummy_cookie=choco; tasty_cookie=strawberry

瀏覽器限制狀況html

  • cookie在chrome中將不在限制數據,可是超過header的容許大小將會報錯jquery

  • firefox限制30個git

  • Opera第個域名限制50個github

demo

爲了簡化操做,我全部的cookie的操做都採用js.cookie的庫,有興趣能夠在github上面讀源碼。面試

方法名 介紹 
Cookies.get(key) 獲取本地key對應的值,不存在返回undefined
Cookies.set(key,value) 將key的值設置成value
Cookies.set(key,{}) 支持直接保存object值
Cookies.set(key1,key2,{}) 支持同時設置多個值
Cookies.remove('key') 移除key的值
Cookies.getJSON('key') 獲取key的值,而且直接序列化成Object

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/js-cookie@2/src/js.cookie.min.js"></script>
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
    <div id="resultDiv">
        <script>
            $(document).ready(function(){
                var visited=0;
                if(Cookies.get('visited')!=undefined){//若是Cookie不存在返回undefined
                    visited=Cookies.get('visited')//獲取訪問次數
                }
                visited++;//添加本次訪問
                Cookies.set('visited',visited)//設置cookie
                document.getElementById('resultDiv').innerHTML=visited
            })
        </script>
    </div>
    
</body>
</html>

上面的demo用來記錄當前客戶端訪問網站的次數ajax

localStorage

localStorage和sessionStorage的接口是一致的,因此本章全部的案例能夠直接改爲sessionStorage.chrome

方法名 做用
localStorage.setItem('key','val') 將key設置成val
localStorage.getItem('key') 獲取key的值
localStorage.removeItem('key') 刪除key的值
localStorage.clear() 刪除全部的值

Demo

獲取訪問次數

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
    <div id="resultDiv"></div>
    <script>
        $(document).ready(function(){
            if(window.localStorage){//瀏覽器是否支持localStorage
                var numHits=localStorage.getItem('numHits');//獲取numHits的值 
                if(!numHits) numHits=0;//若是第一次訪問就置 爲0
                else numHits=parseInt(numHits,10)//轉換成數值 類型
                numHits++
                localStorage.setItem('numHits',numHits)
                $("#resultDiv").text('you have  visited this site '+numHits+'times.')
            }
        })
    </script>
</body>
</html>

上面的做用是在本地存儲一個以numHits的值,表示訪問的次數npm

 

距離上次訪問的時間瀏覽器

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/js-cookie@2/src/js.cookie.min.js"></script>
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
    <div id="resultDiv">
​
    </div>
    <script>
        $(document).ready(function(){
            var $resultDiv=$('#resultDiv')
            var newUser=true;
            var daysSinceLastVisit;
            if(Cookies.get('lastVisit')!=undefined){
                newUser=false;
                var lastVisit=Cookies.get('lastVisit')
                var now=new Date()//當前的時間
                var lastVisitDate=new Date(lastVisit)//lastVisit轉換成date對象
                var timeDiff=Math.abs(now.getTime()-lastVisitDate.getTime())//存在再次時間差
                var daysSinceLastVisit=Math.ceil(timeDiff/(1000*3600*24))//轉換整天
            }
            Cookies.set('lastVisit',new Date(),Infinity)
            if(newUser){
                $resultDiv.text('welcome to the site')
            }else if(daysSinceLastVisit>20){
                $resultDiv.text('welcome back to the site!')
            }else{
                $resultDiv.text('welcome good user!')
            }
        })
​
    </script>
    
</body>
</html>

上次的代碼主要現實的三個功能:

  • 若是初次訪問輸出welcome to the site

  • 若是上次訪問的時間超過20天輸出,welcome back to the site!

  • 若是在20天之內,輸出:welcome good user

存儲表單數據

localStorage實際上只能存儲字符串數據,可是能夠經過JSON.stringify和JSON.parse來存儲Object對象。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
    <form action="#" id="myForm">
        <p>Your name:<input type="text" name="name" id="name"></name:></p>
        <p>Your age:<input type="number" name="age" id="age"></name:></p>
        <p>your email:<input type="email" name="email" id="email"></p>
        <p><input type="submit" ></p>
    </form>
    <script>
        $(document).ready(function(){
            if(window.localStorage){
                if(localStorage.getItem('personForm')){
                    var person=JSON.parse(localStorage.getItem('personForm'))
                    $("#name").val(person.name);
                    $("#age").val(person.age);
                    $("#email").val(person.email)
                    console.log('restored from storage')
                }
                $("input").on('input',function(e){
                    var name=$("#name").val();
                    var age=$("#age").val();
                    var email=$("#email").val();
                    console.log('email',email)
                    var person = { "name": name, "age": age, "email": email }
                    localStorage.setItem("personForm",JSON.stringify(person))
                    console.log('stored the from...')
                })
                $("#myForm").on('submit',function(e){
                    localStorage.removeItem('personForm')
                    return true
                })
            }
        })
    </script>
</body>
</html>

上面的demo主要是:

  1. 監聽全部表單的輸入事件,經過JSON.stringify()來將Object轉換成字符串進行存儲

  2. 進入網站時讀取表單數據,若是存在着personForm的值就直接顯示在頁面上

  3. 點擊提交按鈕清空personForm數據

不一樣頁面進行通訊

有一次面試被問到如何實現幾個標籤的通訊,下面的demo實際上就是作了這麼一個工做。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
    <form action="#" id="myForm">
        <p>Text Value:<input type="text" id="text"></p>
    </form>
    <script>
        $(document).ready(function(){
            if(window.localStorage){
                console.log('test',localStorage.getItem('testValue'))
                if(localStorage.getItem('testValue')!=undefined){
                    console.log('f1')
                    $('#text').val(localStorage.getItem('testValue'))
                }
                $('input').on('input',function(e){
                    var test=$('#text').val()
                    localStorage.setItem('testValue',test)
                    console.log('stored the test value.');
                })
                $(window).on('storage',function(e){
                    console.log('storage event fired');
                    console.dir(e);
                })
            }
        })
    </script>
</body>
</html>

上面的demo咱們打開兩個頁面,第一個頁面輸入內容,第二個頁面就會觸發window的storage事件,事件的參數originalEvent對象中的newValue和oldValue表示上次的值 和當前 的值 。

 

兼容

if (!window.localStorage) {
  Object.defineProperty(window, "localStorage", new (function () {
    var aKeys = [], oStorage = {};
    Object.defineProperty(oStorage, "getItem", {
      value: function (sKey) { return sKey ? this[sKey] : null; },
      writable: false,
      configurable: false,
      enumerable: false
    });
    Object.defineProperty(oStorage, "key", {
      value: function (nKeyId) { return aKeys[nKeyId]; },
      writable: false,
      configurable: false,
      enumerable: false
    });
    Object.defineProperty(oStorage, "setItem", {
      value: function (sKey, sValue) {
        if(!sKey) { return; }
        document.cookie = escape(sKey) + "=" + escape(sValue) + "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/";
      },
      writable: false,
      configurable: false,
      enumerable: false
    });
    Object.defineProperty(oStorage, "length", {
      get: function () { return aKeys.length; },
      configurable: false,
      enumerable: false
    });
    Object.defineProperty(oStorage, "removeItem", {
      value: function (sKey) {
        if(!sKey) { return; }
        document.cookie = escape(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/";
      },
      writable: false,
      configurable: false,
      enumerable: false
    });
    this.get = function () {
      var iThisIndx;
      for (var sKey in oStorage) {
        iThisIndx = aKeys.indexOf(sKey);
        if (iThisIndx === -1) { oStorage.setItem(sKey, oStorage[sKey]); }
        else { aKeys.splice(iThisIndx, 1); }
        delete oStorage[sKey];
      }
      for (aKeys; aKeys.length > 0; aKeys.splice(0, 1)) { oStorage.removeItem(aKeys[0]); }
      for (var aCouple, iKey, nIdx = 0, aCouples = document.cookie.split(/\s*;\s*/); nIdx < aCouples.length; nIdx++) {
        aCouple = aCouples[nIdx].split(/\s*=\s*/);
        if (aCouple.length > 1) {
          oStorage[iKey = unescape(aCouple[0])] = unescape(aCouple[1]);
          aKeys.push(iKey);
        }
      }
      return oStorage;
    };
    this.configurable = false;
    this.enumerable = true;
  })());
}
相關文章
相關標籤/搜索