引言
隨著對(duì)前端的了解越來(lái)越深入佳吞,了解到了很多種瀏覽器的存儲(chǔ)方案,如 Cookie棉安、LocalStorage等底扳,哪這些存儲(chǔ)方案有何異同,分別的適用場(chǎng)景又是什么呢贡耽。
Cookie
Cookie的來(lái)源
Cookie 被創(chuàng)造出來(lái)的本意并不是本地儲(chǔ)存衷模,而是為了辨別用戶身份。眾所周知蒲赂,Http 協(xié)議是無(wú)狀態(tài)的阱冶,也就是說(shuō)你每一次發(fā)送給服務(wù)器的請(qǐng)求對(duì)于服務(wù)器來(lái)說(shuō)都是孤立的,服務(wù)器不知道這這些請(qǐng)求來(lái)自于誰(shuí)滥嘴。比如你向購(gòu)物車(chē)?yán)锩嫣砑恿艘恍┥唐纺镜牛钱?dāng)發(fā)送結(jié)賬請(qǐng)求的時(shí)候服務(wù)器懵了,我怎么知道你是誰(shuí)若皱,你買(mǎi)了什么呢镊叁。而使用 Cookie 之后,服務(wù)器就可以通過(guò)查看 Cookie 來(lái)判斷發(fā)送用戶走触,一定程度上 Cookies 可以說(shuō)是請(qǐng)求的身份證晦譬。可以告訴服務(wù)器請(qǐng)求發(fā)送自誰(shuí)互广。
Cookie是什么
百聞不如一見(jiàn)敛腌,直接來(lái)看看 Cookie 長(zhǎng)啥樣
這是百度首頁(yè)使用的 Cookie ,如你所見(jiàn)惫皱,Cookie 是以 Name-Value 鍵值對(duì)儲(chǔ)存在瀏覽器中的像樊,其中 Value 又是明顯經(jīng)過(guò)了加密的數(shù)據(jù)。
Cookie生成方式
Cookie 是所屬于域名的旅敷,還是百度首頁(yè)的 Cookie凶硅,通過(guò) Domain 屬性可以得知前兩個(gè) Cookie 是屬于 .baidu.com 的
每個(gè)域名只能設(shè)置與訪問(wèn)到自己域名下的 Cookie,比如 baidu.com 無(wú)法訪問(wèn) Domain 為 sougou.com 的 Cookie扫皱。但是子域名可以讀取父域名設(shè)置的Cookie足绅,比如截圖中 www.baidu.com 就讀取到了 Domain='.baidu.com' 的Cookie,通過(guò)手動(dòng)設(shè)置 Domain 可以設(shè)置父域名的 Cookie韩脑,比如 www.baidu.com 可以設(shè)置 Domain='baidu.com'
這樣 *.baidu.com 所有二級(jí)域名也能讀取到它設(shè)置的 Cookie
//www.baidu.com
document.cookie='age=20;domain=.baidu.com'
// 此時(shí) 所有二級(jí)域名可以直接讀取到這個(gè) Cookie
Cookie的生成方式分為 服務(wù)器端生成和瀏覽器端生成氢妈。
- 服務(wù)器端-通過(guò)設(shè)置 http response header中的set-cookie
我們可以通過(guò)響應(yīng)頭里的 Set-Cookie 指定要存儲(chǔ)的 Cookie 值。當(dāng)請(qǐng)求返回瀏覽器的時(shí)候?yàn)g覽器就會(huì)按照 header 中的 set-cookie 值設(shè)置 Cookie段多。默認(rèn)情況下首量,Domain 被設(shè)置為設(shè)置 Cookie 頁(yè)面的主機(jī)名,當(dāng)然我們也可以手動(dòng)設(shè)置 Domain 的值进苍。
Set-Cookie: id=a3fWa;
- 瀏覽器端- js中可以通過(guò)document.cookie可以讀寫(xiě)cookie加缘,以鍵值對(duì)的形式展示
document.cookie="id=a3fWa"
document.cookie='age=20;domain=.baidu.com'
Cookie的應(yīng)用場(chǎng)景
既然 Cookie 的作用就是告訴服務(wù)器請(qǐng)求來(lái)自于誰(shuí),那么最主要的作用就是保持用戶登陸態(tài)(記住密碼)觉啊,除此之外還可以記錄用戶瀏覽數(shù)據(jù)拣宏,進(jìn)行廣告推送和前文提到的購(gòu)物車(chē)等。
Cookie的缺點(diǎn)
缺點(diǎn)其實(shí)在前文中就很顯而易見(jiàn)了
- 不夠大
Cookie 會(huì)隨著每一次請(qǐng)求發(fā)送杠人,這就注定了 Cookie 必定會(huì)有嚴(yán)格的大小限制勋乾,每一個(gè) Cookie 的大小被限制在了 4kb,值得注意的是 4kb 指的是一個(gè) Name-Value 的大小嗡善,而并不是說(shuō)這個(gè)域名可以設(shè)置的 Cookie 總大小只有 4kb
- 性能缺陷
Cookie 是跟隨著域名的辑莫,會(huì)隨著每一個(gè)同域名請(qǐng)求發(fā)送,但是其實(shí)很大一部分請(qǐng)求罩引,比如說(shuō)圖片等靜態(tài)資源的請(qǐng)求是完全用不著 Cookie 的各吨,雖然每個(gè)Cookie只有 4kb 但是積少成多也會(huì)帶來(lái)巨大的資源浪費(fèi)。
我們可以把靜態(tài)資源放到 CDN 上去袁铐,這時(shí)候圖片域名就和主站域名不相同了揭蜒,就不會(huì)附帶發(fā)送 Cookie
- 不夠安全
正如上文直接打開(kāi)控制臺(tái)就可以看到 Cookie 一樣,Cookie 雖然通過(guò)編碼進(jìn)行了加密昭躺,但在 Http 傳輸中是明文傳輸忌锯,腳本也可以很輕松的獲取到 Cookie,非常容易被破解领炫。
在服務(wù)器端設(shè)置 Cookie 的時(shí)候附帶上 HttpOnly 標(biāo)記偶垮,這樣在瀏覽器端就無(wú)法使用 document.cookie 訪問(wèn)到這個(gè) Cookie 了
Set-Cookie: id=a3fWa; HttpOnly
標(biāo)記為 Secure 的 Cookie 只應(yīng)通過(guò) Https 協(xié)議加密過(guò)的請(qǐng)求發(fā)送,但是即便如此也不應(yīng)該使用 Cookie 儲(chǔ)存敏感信息帝洪,因?yàn)?Cookie 有其固有的不安全性似舵,這兩個(gè)標(biāo)記也無(wú)法提供確切的安全保障。
解決方法
既然 Cookie 有這么多缺點(diǎn)葱峡,有沒(méi)有什么一勞永逸的解決方法呢砚哗,那就是「專(zhuān)業(yè)的人做專(zhuān)業(yè)的事」。
用戶登錄態(tài)和部分用戶信息的存儲(chǔ)的工作交給 Seesion ---即 Cookie 只用來(lái)儲(chǔ)存一個(gè)用戶唯一標(biāo)識(shí)符砰奕,真正信息儲(chǔ)存在服務(wù)器端蛛芥,使用 Cookie 作為 SeesionID 去服務(wù)器查找信息提鸟,這樣一來(lái) Cookie 的容量限制,安全問(wèn)題都引刃而解了仅淑,因?yàn)榇藭r(shí) Cookie 里面就是一串無(wú)意義的隨機(jī)碼称勋。
本地儲(chǔ)存得工作交由 HTML5 中新增本地存儲(chǔ)的解決方案 「Web Storage」 ,它又分成兩類(lèi) :localStorage 和 SessionStorage 涯竟,接下來(lái)就介紹這兩兄弟赡鲜。
LocalStorage
特點(diǎn)
- 數(shù)據(jù)長(zhǎng)時(shí)間保存,直到手動(dòng)刪除為止
- 大小約為 5M
- 和 Cookie 一樣庐船,一個(gè)網(wǎng)站只能訪問(wèn)和操作自己網(wǎng)站域名下的數(shù)據(jù)
- 僅在客戶端使用银酬,和服務(wù)端無(wú)通信
- 接口封裝較好
- 使用鍵值對(duì)保存信息
- 同源窗口都可以訪問(wèn)
使用示例
LocalStorage 使用非常方便:
// 設(shè)置數(shù)據(jù)
localStorage.setItem("key","value");
//讀取數(shù)據(jù)
let valueLocal = localStorage.getItem("key");
使用場(chǎng)景
通過(guò)上面那些特性就可以看出 LocalStorage 非常適合用來(lái)做本地緩存,可以提高首屏加載速度筐钟。一些圖片等不會(huì)經(jīng)常改變的大資源也可以緩存下來(lái)揩瞪,減少網(wǎng)絡(luò)請(qǐng)求。
SeesionStorage
特點(diǎn)
- 保存時(shí)間為本次會(huì)話盗棵,也就是說(shuō)窗口關(guān)閉就沒(méi)了
- 僅本窗口可以訪問(wèn)壮韭,同源的其他窗口都不行
- 大小約為 5M
使用場(chǎng)景
sessionStorage 更適合用來(lái)存儲(chǔ)生命周期和它同步的會(huì)話級(jí)別的信息。這些信息只適用于當(dāng)前會(huì)話纹因,比如可以用來(lái)做表單數(shù)據(jù)的持久化喷屋,防止刷新后表單數(shù)據(jù)丟失
Cookie、LocalStorage 和SessionStorage 之間的區(qū)別
作用域的不同
這三者都遵循協(xié)議瞭恰,即同協(xié)議屯曹,同域名,同端口下才能訪問(wèn)和修改同一份數(shù)據(jù)惊畏,唯一不同的就是 SeesionStorage 還要求在同一窗口恶耽。
生命周期的不同
Cookie 可以手動(dòng)設(shè)置過(guò)期時(shí)間,默認(rèn)就是本次會(huì)話時(shí)長(zhǎng)颜启,隨著窗口關(guān)閉而刪除偷俭,當(dāng)設(shè)置了過(guò)期時(shí)間時(shí)候,就會(huì)被儲(chǔ)存到硬盤(pán)中直到過(guò)期時(shí)間才被刪除
LocalStorage 是持久化的本地儲(chǔ)存缰盏,除非你手動(dòng)刪除涌萤,否則會(huì)一直存在
SessionStorage 是會(huì)話級(jí)別的存儲(chǔ),也是隨著窗口關(guān)閉而刪除口猜。
總結(jié)
這就是幾種瀏覽器存儲(chǔ)方案负溪,當(dāng)然還有我們應(yīng)該根據(jù)不同方案各自的特點(diǎn)決定什么時(shí)候使用什么方案,適合的才是最好的济炎〈眨總結(jié)一下本文的幾個(gè)重點(diǎn)
- Cookie 的本職工作并非本地存儲(chǔ),而是“維持狀態(tài)”
- Web Storage 是 HTML5 專(zhuān)門(mén)為瀏覽器存儲(chǔ)而提供的數(shù)據(jù)存儲(chǔ)機(jī)制须尚,不與服務(wù)端發(fā)生通信