Cookie與本地存儲(chǔ)

1.cookie

是由W3C組織提出,最早由Netscape社區(qū)發(fā)展的一種機(jī)制。由于HTTP是一種無狀態(tài)的協(xié)議,服務(wù)器單從網(wǎng)絡(luò)連接上無從知道客戶身份。怎么辦呢?就給客戶端們頒發(fā)一個(gè)通行證吧,每人一個(gè),無論誰訪問都必須攜帶自己通行證。這樣服務(wù)器就能從通行證上確認(rèn)客戶身份了。這就是Cookie的工作原理。

簡(jiǎn)單說cookie會(huì)話跟蹤技術(shù)

在一次會(huì)話從開始到結(jié)束的整個(gè)過程中,全程跟蹤記錄客戶端的狀態(tài),例如是否登錄,購(gòu)物車信息, 是否已經(jīng)下載,是否已經(jīng)點(diǎn)贊,視頻播放進(jìn)度等

1.1. cookie的作用與特性

cookie是存儲(chǔ)在瀏覽器中的緩存信息

1.1.1 作用:
  1. 登錄記錄
  2. 多個(gè)頁面的數(shù)據(jù)傳遞
  3. 保存用戶信息
1.1.2 完整的格式

name=value;[expires=date];[path=path]

1.1.3 特點(diǎn):
  1. 存值不大(最大可以存4kb)
  2. 每個(gè)域名下最多存儲(chǔ)50條數(shù)據(jù)(不同瀏覽器會(huì)有不同)
  3. 可以自己設(shè)置過期時(shí)間
  4. 具有不可跨域性
1.1.4 中文的編碼

中文與英文字符不同,中文屬于Unicode字符,在內(nèi)存中占2個(gè)字符(4個(gè)字節(jié)),而英文屬于ASCII字符,內(nèi)存中只占2個(gè)字節(jié)。Cookie中使用Unicode字符時(shí)需要對(duì)Unicode字符進(jìn)行編碼,否則會(huì)亂碼。

所以cookie直接存中文可能會(huì)出現(xiàn)亂碼

encodeURIComponent 將中文編譯成對(duì)應(yīng)的字符

decodeURIComponent 將對(duì)應(yīng)的字符轉(zhuǎn)為中文

這兩個(gè)方法互逆,都是window上帶的方法,可以直接用

  <script>
    let str = '心存美好'
    let aa =encodeURIComponent(str);
    console.log(aa);
    let bb = decodeURIComponent(aa)
    console.log(bb)
  </script>
1.2. 設(shè)置cookie

我們可以先檢查緩存cookie

console.log(document.cookie)//實(shí)際上設(shè)置cookie之前是沒有cookie值的

設(shè)置cookie

document.cookie = 'name=wuwei'
  <script>
    //檢查/獲取本地cookie
    console.log(document.cookie)
    //設(shè)置本地cookie
    document.cookie = 'name=心存美好' //表示一條cookie記錄  有屬性和值
    document.cookie = 'age=18';
    document.cookie = 'hooby=sing'
 //控制臺(tái)-->Application-->Storage(左側(cè))-->Cookies-->127.0.0.1:5500服務(wù)中可以看到記錄
  </script>

默認(rèn)cookie的結(jié)束時(shí)間是關(guān)閉瀏覽器的時(shí)候

1.3.. 設(shè)置過期時(shí)間

設(shè)置cookie的過期時(shí)間使用expires

  <script>    //  console.log(new Date)//時(shí)間對(duì)象格式    //  console.log(new Date().toGMTString())//字符串時(shí)間格式    let date = new Date(new Date().getTime() + 3000);//用getTime先轉(zhuǎn)成毫秒數(shù),加上3000ms,再轉(zhuǎn)成時(shí)間    document.cookie = `name=美好;expires=${date.toGMTString()}`    //cookie時(shí)間過期會(huì)自動(dòng)刪除cookie,過期就訪問不到    console.log(date)  </script>
 <script>
    //max-age設(shè)置cookie時(shí)間
    document.cookie = `name=美好;max-age=${3}`//單位是s,超過時(shí)間自動(dòng)刪除也可以寫成`name=美好;max-age=3`
 </script>

過期時(shí)間不能小于當(dāng)前時(shí)間,因?yàn)樾∮诋?dāng)前時(shí)間,說明cookie已經(jīng)過期了

var date = new Date(new Date().getTime() -1) ;

所謂的刪除cookie 就是讓cookie 已經(jīng)到達(dá)過期時(shí)間, cookie一旦過期, 會(huì)自動(dòng)刪除

<script>
    
    document.cookie = 'name=美好'
    del.onclick = function () {
      let date = new Date(new Date().getTime() - 10);//設(shè)置成-10就會(huì)立即過期//刪除方法一
      document.cookie = `name=美好;expires=${date.toGMTString()}`
      // document.cookie = `name=美好;max-age = ${0}`//刪除方法二
    }
  </script>
1.4. 設(shè)置多個(gè)cookie
var date = new Date(new Date().getTime() + 30 * 60 * 1000);
document.cookie = 'name=wuwei;expires =' + date.toGMTString();
document.cookie = 'pwd=w123456;expires =' + date.toGMTString();
console.log(document.cookie)
1.5. 封裝設(shè)置cookie
1.5.1 設(shè)置cookie
// 封裝的設(shè)置一個(gè)cookie的函數(shù)
function setCookie(data){
    var date = new Date(new Date().getTime() + data.time * 60* 1000).toGMTString();
    document.cookie = data.name +'='+ data.value+';expires='+date

}
setCookie({
    name:'zhangsan',
    value:18,
    time:5
})

// 設(shè)置單個(gè)cookie
function setCookie(name,value,{expires, path, domain, secure}){
    var cookieStr = encodeURIComponent(name) + '=' + encodeURIComponent(value)
    
    if(expires){
        cookieStr += ';expries=' + afterOfDate(expires)
    }
    
    if(path){
        cookieStr += ";path=" + path
    }
    
    if(domain){
        cookieStr += ";path=" + domain
    }
    
    if(secure){
        cookieStr += ";secure"
    }
    
    document.cookie = cookieStr
}

function afterOfDate(n){
    var d = new Date()
    var day = d.getDate();
    d.setDate(n + day)
    return d
}
  <script>
    // 封裝cookie設(shè)置
    function setCookie(data) {
      let date = new Date(new Date().getTime() + data.expires);
      let cookie = `${data.name}=${data.value};data.expires=${date.toGMTString()}`
      if (data.path) {//如果存在這個(gè)屬性就加上
        cookie += ";path=" + path
      }
      if (data.domain) {
        cookie += ";domain=" + domain
      }
      if (data.secure) {
        cookie += ";secure" + secure
      }
      document.cookie = cookie;

    }
    setCookie({
      name: 'age',//cookie字段名
      value: 18,//字段值
      expires: 3000,//過期時(shí)間
      path: '/',
    })
  </script>
1.5.2 封裝獲取getCookie
function getCookie(name){
    var cookieStr = decodeURIComponent(document.cookie)
    var start = cookieStr.indexOf(name + '=')
    
    if(start == -1){
        return null
    }else{
        // 查詢結(jié)束的位置
        var end = cookieStr.indexOf(";", start)
        if(end == -1){
            end = cookieStr.length
        }
        
        var str = cookieStr.substring(start,end)
        return str.split("=")[1]
    }
}
1.5.3 封裝刪除cookie

清除cookie

思路就是將cookie時(shí)間設(shè)置為已經(jīng)過期的時(shí)間瀏覽器會(huì)自動(dòng)清楚過期的cookie

function removeCookie(name){
    document.cookie = encodeURIComponet(name) + "=;expires=" + new Date(0)
}
1.6. 封裝設(shè)置多個(gè)cookie
function setCookie(data){
    data.forEach((item,index)=>{
        var date = new Date(new Date().getTime() + item.time * 60* 1000).toGMTString();
        document.cookie = item.name +'='+ item.value+';expires='+date
    })

}
setCookie([
    {
        name:'zhangsan',
        value:18,
        time:5
    },{
        name:'lisi',
        value:30,
        time:10
    },{
        name:'wangwu',
        value:41,
        time:10
    }
])
1.7. 設(shè)置所有cookie常用的屬性
屬性 描述
name 該Cookie的名稱。Cookie一旦創(chuàng)建,名稱便不可更改
value 該Cookie的值。如果值為Unicode字符,需要為字符編碼。
expires 設(shè)置cookie的過期時(shí)間使用expires(確定的時(shí)間)
maxAge max-age用秒來設(shè)置cookie的生存期(5*24*60*60)
path 該Cookie的使用路徑
domain 可以訪問該Cookie的域名。(localhost)
secure 該Cookie是否僅被使用安全協(xié)議傳輸。安全協(xié)議。默認(rèn)為false<br />如果不設(shè)置字段 cookie 可以通過http,https 協(xié)議加載設(shè)置<br />如果設(shè)置這個(gè)字段, 那么只能通過https協(xié)議才能設(shè)置成
HTTP-Only HTTP-Only 背后的意思是告之瀏覽器該 cookie 絕不能通過 JavaScript 的 document.cookie屬性訪問。<br />默認(rèn)是false(沒有值),前端就可以訪問。如果值為true,則只有后端可以訪問前端不可以訪問。<br />控制臺(tái)中雙擊就可以true、false切換

2.本地存儲(chǔ)

本地存儲(chǔ)是HTML5中新增的特性,用來解決cookie存儲(chǔ)空間不足的問題

1、概述:

對(duì)于Web Storage來說,實(shí)際上是Cookies存儲(chǔ)的進(jìn)化版。

背熟這句口訣:“兩個(gè)接口,四個(gè)函數(shù)”。

2、口訣:

(1)兩個(gè)接口:分別是sessonStorage(臨時(shí)存儲(chǔ))和localStorage(本地存儲(chǔ))

(2)四個(gè)函數(shù):分別是setItem、getItem、removeItem和clear。(設(shè)置、獲取、刪除、)

2.1. Storage
2.1.1 sessionStorage
session臨時(shí)回話,從頁面打開到頁面關(guān)閉的時(shí)間段
窗口的臨時(shí)存儲(chǔ),頁面關(guān)閉,本地存儲(chǔ)消失

臨時(shí)存儲(chǔ)就是存儲(chǔ)一下,其他頁面并不會(huì)共享
<body>
  <!-- 本地存儲(chǔ) -->
  <input type="text" name="" id="text">
  <button id="addData">設(shè)置</button>
  <button id="addData2">設(shè)置2</button>
  <button id="addData3">設(shè)置3</button>
  <button id="getData">獲取</button>
  <button id="removeData">刪除</button>
  <button id="clearData">清空</button>
  <div id="box"></div>
  <div id="box3"></div>
  <!--獲取的數(shù)據(jù)內(nèi)容添加到這里 -->

  <script>
    //查看臨時(shí)會(huì)話 控制臺(tái)--》Application-->storage-->sesssion Storage--->127.0.0.1:5500。頁面關(guān)閉時(shí)數(shù)據(jù)就消失
    addData.onclick = function () {//設(shè)置
      console.log(11);
      if (text.value.trim()) {//點(diǎn)擊設(shè)置,判斷是否有值
        sessionStorage.setItem('name', text.value)//有值設(shè)置input的值,設(shè)置后在Application-->storage-->sesssion Storage--->127.0.0.1:5500就會(huì)看到,要?jiǎng)h除默認(rèn)的值
      } else {
        alert('請(qǐng)輸入內(nèi)容')//點(diǎn)擊設(shè)置,為空出現(xiàn)彈框
      }
    }
    addData2.onclick = function () {//設(shè)置的另一個(gè)age值,字段名和字段值一一對(duì)應(yīng)
      console.log(11);
      if (text.value.trim()) {
        sessionStorage.setItem('age', text.value)
      } else {
        alert('請(qǐng)輸入內(nèi)容')
      }
    }
    addData3.onclick = function () {//設(shè)置的另一個(gè)age值,字段名和字段值一一對(duì)應(yīng)
      console.log(11);
      if (text.value.trim()) {
        sessionStorage.setItem('user', JSON.stringify({
          name: '張五', age: '50'
        }))//即使存儲(chǔ)的是對(duì)象,控制臺(tái)里也會(huì)自動(dòng)轉(zhuǎn)成字符串[object,Object]。要使用JSON.stringify轉(zhuǎn)成字符串才是對(duì)象字符串
      } else {
        alert('請(qǐng)輸入內(nèi)容')
      }
    }
    getData.onclick = function () {
      console.log(22)
      let data = sessionStorage.getItem('name')//傳獲取的字段名,要獲取name字段名
      box.innerHTML = data;//點(diǎn)擊‘獲取’就將input里的值取出來了,放到頁面上了
      let data3 = sessionStorage.getItem('user')
      console.log(typeof data3)
      console.log(data3)//這時(shí)是字符串
      console.log(JSON.parse(data3))//通過JSON.parse轉(zhuǎn)成了對(duì)象,點(diǎn)開控制臺(tái)原型可以看到
      box3.innerHTML = data3;
    }
    removeData.onclick = function () {
      console.log(33)
      sessionStorage.removeItem('name')
    }
    clearData.onclick = function () {
      console.log(44);
      sessionStorage.clear()//全部干掉了
    }
    //  特性
    // 1.sessionStorage是臨時(shí)會(huì)話,如果頁面關(guān)閉數(shù)據(jù)自動(dòng)刪除
    // 2.數(shù)據(jù)不共享,即使同一個(gè)網(wǎng)站同一個(gè)頁面數(shù)據(jù)也不共享。
    // 3.存儲(chǔ)的數(shù)據(jù)都是字符串,如果想要存對(duì)象或數(shù)組,先使用JSON轉(zhuǎn)成字符串
  </script>
</body>

JSON是js內(nèi)置的一個(gè)對(duì)象。JSON是有固定格式的字符串。JSON里面的字段必須要雙引。

  
    // JSON.stringify()  把對(duì)象類型轉(zhuǎn)成字符串
    // JSON.parse()      把字符串解析成對(duì)象
    let obj = {  //這個(gè)數(shù)據(jù)傳給后端時(shí),后端不一定識(shí)別,但字符串是所有瀏覽器都能識(shí)別的,通過JSON.stringify()轉(zhuǎn)成字符串
      name: '張三',
      age: 19
    }
    let aa = JSON.stringify(obj)   //對(duì)象轉(zhuǎn)字符串
    let bb = JSON.parse(aa)//字符串解析成對(duì)象
    console.log(typeof aa)
    console.log(typeof bb)
    // JSON對(duì)象:對(duì)象格式的JSON
    // JSON數(shù)組:數(shù)組格式的JSON
    let arr = [10, 20, 30, { name: '張三' }]
    let arrJSON = JSON.stringify(arr)
    console.log(arrJSON)
    console.log(typeof arrJSON)//數(shù)組格式的JSON
    console.log(JSON.parse(arrJSON))//此時(shí)又將json轉(zhuǎn)成數(shù)組了
  // JSON在js中外部需要加單引號(hào)'',JSON單獨(dú)創(chuàng)建xxx.json文件時(shí)就不需要單引號(hào)了,直接在文件里寫內(nèi)容就可以{"":"","":""},json文件里也都需要雙引號(hào)
2.1.2 localStorage
域內(nèi)安全、永久保存。瀏覽器不刪除,會(huì)一直存儲(chǔ)著數(shù)據(jù)。即客戶端或?yàn)g覽器中來自同一域名的所有頁面都可訪問localStorage數(shù)據(jù)且數(shù)據(jù)除了刪除否則永久保存,但客戶端或?yàn)g覽器之間的數(shù)據(jù)相互獨(dú)立。

永久存儲(chǔ)(可以手動(dòng)刪除數(shù)據(jù))

多個(gè)頁面可以共享
<body>
  <!-- 本地存儲(chǔ) -->
  <input type="text" name="" id="text">
  <button id="addData">設(shè)置</button>
  <button id="addData2">設(shè)置2</button>
  <button id="addData3">設(shè)置3</button>
  <button id="getData">獲取</button>
  <button id="removeData">刪除</button>
  <button id="clearData">清空</button>
  <div id="box"></div>
  <div id="box3"></div>
  <script>
    //此時(shí)打開控制臺(tái) --》Application-->localStorage中沒有數(shù)據(jù)。
    //輸入數(shù)據(jù)后--》點(diǎn)設(shè)置,控制臺(tái)中就有數(shù)據(jù)了。
    //此時(shí)再開啟新頁面,控制臺(tái)中剛剛設(shè)置的數(shù)據(jù)依然存在
    addData.onclick = function () {
      console.log(11);
      if (text.value.trim()) {
        localStorage.setItem('name', text.value)
      } else {
        alert('請(qǐng)輸入內(nèi)容')
      }
    }
    addData2.onclick = function () {
      console.log(11);
      if (text.value.trim()) {
        localStorage.setItem('age', text.value)
      } else {
        alert('請(qǐng)輸入內(nèi)容')
      }
    }
    addData3.onclick = function () {
      console.log(11);
      if (text.value.trim()) {
        localStorage.setItem('user', JSON.stringify({
          name: '張五', age: '50'
        }))
      } else {
        alert('請(qǐng)輸入內(nèi)容')
      }
    }
    getData.onclick = function () {
      console.log(22)
      let data = localStorage.getItem('name')
      box.innerHTML = data;
    }
    removeData.onclick = function () {
      console.log(33)
      localStorage.removeItem('name')
    }
    clearData.onclick = function () {
      console.log(44);
      localStorage.clear()
    }

  </script>
</body>
2.2. Storage的特點(diǎn)
  1. 永久存儲(chǔ)
  2. 存儲(chǔ)量限制 ( 5M ) 客戶端微型數(shù)據(jù)庫
  3. 客戶端完成,不會(huì)請(qǐng)求服務(wù)器處理
  4. sessionStorage數(shù)據(jù)是不共享、 localStorage共享
  5. 瀏覽器不統(tǒng)一,并且在IE8以下不兼容
  6. 儲(chǔ)存的值限定是字符串類型,需要我們通過JSON 對(duì)象去轉(zhuǎn)換
  7. 存儲(chǔ)內(nèi)容多的話會(huì)消化內(nèi)容空間,會(huì)導(dǎo)致變卡
2.3. Storage API
2.3.1 setItem(鍵名,鍵值):
設(shè)置數(shù)據(jù),(key,value)類型,類型都是字符串
可以用獲取屬性的形式操作

在本地客戶端存儲(chǔ)一個(gè)字符串類型的數(shù)據(jù),其中,第一個(gè)參數(shù)“鍵名”代表了該數(shù)據(jù)的標(biāo)識(shí)符,而第二個(gè)參數(shù)“鍵值”為該數(shù)據(jù)本身。

例如:

 localStorage.setItem("name", "wuwei");
2.3.2 getItem():
讀取已存儲(chǔ)在本地的數(shù)據(jù),通過鍵名作為參數(shù)讀取出對(duì)應(yīng)鍵名的數(shù)據(jù)。如:

獲取數(shù)據(jù),通過key來獲取到相應(yīng)的value
var data = localStorage.getItem("name"); 
2.3.3 removeItem():
移除已存儲(chǔ)在本地的數(shù)據(jù),通過鍵名作為參數(shù)刪除對(duì)應(yīng)鍵名的數(shù)據(jù)。

刪除數(shù)據(jù),通過key來刪除相應(yīng)的value
 localStorage.removeItem("name");   
2.3.4 clear():
移除本地存儲(chǔ)所有數(shù)據(jù)。刪除全部存儲(chǔ)的值
localStorage.clear();  
示例:
<button id="addData">添加數(shù)據(jù)</button>
<button id="getData">獲取數(shù)據(jù)</button>
<button id="removeData">刪除數(shù)據(jù)</button>
<input type="text" id="txt">

<script>
    addData.onclick = function () {
        sessionStorage.setItem('name', txt.value);
    }
    getData.onclick = function () {
        alert(sessionStorage.getItem('name'))
    }
    removeData.onclick = function () {
        sessionStorage.removeItem('name')
    }
</script>

臨時(shí)存儲(chǔ),只要頁面不關(guān)閉,無論怎么刷新,數(shù)據(jù)都不會(huì)刪除

2.3.5 存儲(chǔ)事件:(了解就OK)
當(dāng)數(shù)據(jù)有修改或刪除的情況下,就會(huì)觸發(fā)storage事件
在對(duì)數(shù)據(jù)進(jìn)行改變的窗口對(duì)象上是不會(huì)觸發(fā)的
  1. Key : 修改或刪除的key值,如果調(diào)用clear(),key為null
  2. newValue : 新設(shè)置的值,如果調(diào)用removeStorage(),key為null
  3. oldValue : 調(diào)用改變前的value值
  4. storageArea : 當(dāng)前的storage對(duì)象
  5. url : 觸發(fā)該腳本變化的文檔的url
    注:session同窗口才可以,例子:iframe操作
window.addEventListener('storage',function(ev){
    console.log(ev.key);
    console.log(ev.newValue  );
    console.log(ev.oldValue );
    console.log(ev.storageArea );
    console.log(ev.url);
})
2.3.6 兼容問題

那么在老古董瀏覽器上,可以通過使用Cookies來做替代方案并做好域內(nèi)安全。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容