摘要:優(yōu)異的性能表現(xiàn),有一部分原因要歸功于瀏覽器存儲技術(shù)的提升。是服務(wù)端生成,客戶端進行維護和存儲。當超過時,它將面臨被裁切的命運。此外很多瀏覽器對一個站點的個數(shù)也是有限制的。存入讀取數(shù)據(jù)保存的數(shù)據(jù),以鍵值對的形式存在。
前言
隨著移動網(wǎng)絡(luò)的發(fā)展與演化,我們手機上現(xiàn)在除了有原生 App,還能跑“WebApp”——它即開即用,用完即走。一個優(yōu)秀的 WebApp 甚至可以擁有和原生 App 媲美的功能和體驗。WebApp 優(yōu)異的性能表現(xiàn),有一部分原因要歸功于瀏覽器存儲技術(shù)的提升。cookie存儲數(shù)據(jù)的功能已經(jīng)很難滿足開發(fā)所需,逐漸被WebStorage、IndexedDB所取代,本文將介紹這幾種存儲方式的差異和優(yōu)缺點。
想閱讀更多優(yōu)質(zhì)文章請猛戳GitHub博客
一、Cookie 1.Cookie的來源Cookie 的本職工作并非本地存儲,而是“維持狀態(tài)”。
因為HTTP協(xié)議是無狀態(tài)的,HTTP協(xié)議自身不對請求和響應(yīng)之間的通信狀態(tài)進行保存,通俗來說,服務(wù)器不知道用戶上一次做了什么,這嚴重阻礙了交互式Web應(yīng)用程序的實現(xiàn)。在典型的網(wǎng)上購物場景中,用戶瀏覽了幾個頁面,買了一盒餅干和兩瓶飲料。最后結(jié)帳時,由于HTTP的無狀態(tài)性,不通過額外的手段,服務(wù)器并不知道用戶到底買了什么,于是就誕生了Cookie。它就是用來繞開HTTP的無狀態(tài)性的“額外手段”之一。服務(wù)器可以設(shè)置或讀取Cookies中包含信息,借此維護用戶跟服務(wù)器會話中的狀態(tài)。
我們可以把Cookie 理解為一個存儲在瀏覽器里的一個小小的文本文件,它附著在 HTTP 請求上,在瀏覽器和服務(wù)器之間“飛來飛去”。它可以攜帶用戶信息,當服務(wù)器檢查 Cookie 的時候,便可以獲取到客戶端的狀態(tài)。
在剛才的購物場景中,當用戶選購了第一項商品,服務(wù)器在向用戶發(fā)送網(wǎng)頁的同時,還發(fā)送了一段Cookie,記錄著那項商品的信息。當用戶訪問另一個頁面,瀏覽器會把Cookie發(fā)送給服務(wù)器,于是服務(wù)器知道他之前選購了什么。用戶繼續(xù)選購飲料,服務(wù)器就在原來那段Cookie里追加新的商品信息。結(jié)帳時,服務(wù)器讀取發(fā)送來的Cookie就行了。
2.什么是Cookie及應(yīng)用場景Cookie指某些網(wǎng)站為了辨別用戶身份而儲存在用戶本地終端上的數(shù)據(jù)(通常經(jīng)過加密)。 cookie是服務(wù)端生成,客戶端進行維護和存儲。通過cookie,可以讓服務(wù)器知道請求是來源哪個客戶端,就可以進行客戶端狀態(tài)的維護,比如登陸后刷新,請求頭就會攜帶登陸時response header中的set-cookie,Web服務(wù)器接到請求時也能讀出cookie的值,根據(jù)cookie值的內(nèi)容就可以判斷和恢復(fù)一些用戶的信息狀態(tài)。
如上圖所示,Cookie 以鍵值對的形式存在。
典型的應(yīng)用場景有:
記住密碼,下次自動登錄。
購物車功能。
記錄用戶瀏覽數(shù)據(jù),進行商品(廣告)推薦。
3.Cookie的原理及生成方式Cookie的原理
第一次訪問網(wǎng)站的時候,瀏覽器發(fā)出請求,服務(wù)器響應(yīng)請求后,會在響應(yīng)頭里面添加一個Set-Cookie選項,將cookie放入到響應(yīng)請求中,在瀏覽器第二次發(fā)請求的時候,會通過Cookie請求頭部將Cookie信息發(fā)送給服務(wù)器,服務(wù)端會辨別用戶身份,另外,Cookie的過期時間、域、路徑、有效期、適用站點都可以根據(jù)需要來指定。
Cookie的生成方式主要有兩種:
生成方式一:http response header中的set-cookie
我們可以通過響應(yīng)頭里的 Set-Cookie 指定要存儲的 Cookie 值。默認情況下,domain 被設(shè)置為設(shè)置 Cookie 頁面的主機名,我們也可以手動設(shè)置 domain 的值。
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2018 07:28:00 GMT;//可以指定一個特定的過期時間(Expires)或有效期(Max-Age)
當Cookie的過期時間被設(shè)定時,設(shè)定的日期和時間只與客戶端相關(guān),而不是服務(wù)端。
生成方式二:js中可以通過document.cookie可以讀寫cookie,以鍵值對的形式展示
例如我們在掘金社區(qū)控制臺輸入以下三句代碼,便可以在Chrome 的 Application 面板查看生成的cookie:
document.cookie="userName=hello"
document.cookie="gender=male"
document.cookie="age=20;domain=.baidu.com"
從上圖中我們可以得出:
Domain 標識指定了哪些域名可以接受Cookie。如果沒有設(shè)置domain,就會自動綁定到執(zhí)行語句的當前域。
如果設(shè)置為”.baidu.com”,則所有以”baidu.com”結(jié)尾的域名都可以訪問該Cookie,所以在掘金社區(qū)上讀取不到第三條代碼存儲Cookie值。
Cookie 不夠大
Cookie的大小限制在4KB左右,對于復(fù)雜的存儲需求來說是不夠用的。當 Cookie 超過 4KB 時,它將面臨被裁切的命運。這樣看來,Cookie 只能用來存取少量的信息。此外很多瀏覽器對一個站點的cookie個數(shù)也是有限制的。
這里需注意:各瀏覽器的cookie每一個name=value的value值大概在4k,所以4k并不是一個域名下所有的cookie共享的,而是一個name的大小。
過多的 Cookie 會帶來巨大的性能浪費
Cookie 是緊跟域名的。同一個域名下的所有請求,都會攜帶 Cookie。大家試想,如果我們此刻僅僅是請求一張圖片或者一個 CSS 文件,我們也要攜帶一個 Cookie 跑來跑去(關(guān)鍵是 Cookie 里存儲的信息并不需要),這是一件多么勞民傷財?shù)氖虑?。Cookie 雖然小,請求卻可以有很多,隨著請求的疊加,這樣的不必要的 Cookie 帶來的開銷將是無法想象的。
cookie是用來維護用戶信息的,而域名(domain)下所有請求都會攜帶cookie,但對于靜態(tài)文件的請求,攜帶cookie信息根本沒有用,此時可以通過cdn(存儲靜態(tài)文件的)的域名和主站的域名分開來解決。
由于在HTTP請求中的Cookie是明文傳遞的,所以安全性成問題,除非用HTTPS。
5.Cookie與安全對于 cookie 來說,我們還需要注意安全性。
HttpOnly 不支持讀寫,瀏覽器不允許腳本操作document.cookie去更改cookie,
所以為避免跨域腳本 (XSS) 攻擊,通過JavaScript的 Document.cookie API無法訪問帶有 HttpOnly 標記的Cookie,它們只應(yīng)該發(fā)送給服務(wù)端。如果包含服務(wù)端 Session 信息的 Cookie 不想被客戶端 JavaScript 腳本調(diào)用,那么就應(yīng)該為其設(shè)置 HttpOnly 標記。
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly
標記為 Secure 的Cookie只應(yīng)通過被HTTPS協(xié)議加密過的請求發(fā)送給服務(wù)端。但即便設(shè)置了 Secure 標記,敏感信息也不應(yīng)該通過Cookie傳輸,因為Cookie有其固有的不安全性,Secure 標記也無法提供確實的安全保障。
為了彌補 Cookie 的局限性,讓“專業(yè)的人做專業(yè)的事情”,Web Storage 出現(xiàn)了。
HTML5中新增了本地存儲的解決方案----Web Storage,它分成兩類:sessionStorage和localStorage。這樣有了WebStorage后,cookie能只做它應(yīng)該做的事情了——作為客戶端與服務(wù)器交互的通道,保持客戶端狀態(tài)。
二、LocalStorage 1.LocalStorage的特點保存的數(shù)據(jù)長期存在,下一次訪問該網(wǎng)站的時候,網(wǎng)頁可以直接讀取以前保存的數(shù)據(jù)。
大小為5M左右
僅在客戶端使用,不和服務(wù)端進行通信
接口封裝較好
基于上面的特點,LocalStorage可以作為瀏覽器本地緩存方案,用來提升網(wǎng)頁首屏渲染速度(根據(jù)第一請求返回時,將一些不變信息直接存儲在本地)。
2.存入/讀取數(shù)據(jù)localStorage保存的數(shù)據(jù),以“鍵值對”的形式存在。也就是說,每一項數(shù)據(jù)都有一個鍵名和對應(yīng)的值。所有的數(shù)據(jù)都是以文本格式保存。
存入數(shù)據(jù)使用setItem方法。它接受兩個參數(shù),第一個是鍵名,第二個是保存的數(shù)據(jù)。
localStorage.setItem("key","value");
讀取數(shù)據(jù)使用getItem方法。它只有一個參數(shù),就是鍵名。
var valueLocal = localStorage.getItem("key");
具體步驟,請看下面的例子:
3.使用場景
LocalStorage在存儲方面沒有什么特別的限制,理論上 Cookie 無法勝任的、可以用簡單的鍵值對來存取的數(shù)據(jù)存儲任務(wù),都可以交給 LocalStorage 來做。
這里給大家舉個例子,考慮到 LocalStorage 的特點之一是持久,有時我們更傾向于用它來存儲一些內(nèi)容穩(wěn)定的資源。比如圖片內(nèi)容豐富的電商網(wǎng)站會用它來存儲 Base64 格式的圖片字符串:
三、sessionStoragesessionStorage保存的數(shù)據(jù)用于瀏覽器的一次會話,當會話結(jié)束(通常是該窗口關(guān)閉),數(shù)據(jù)被清空;sessionStorage 特別的一點在于,即便是相同域名下的兩個頁面,只要它們不在同一個瀏覽器窗口中打開,那么它們的 sessionStorage 內(nèi)容便無法共享;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。除了保存期限的長短不同,SessionStorage的屬性和方法與LocalStorage完全一樣。
1.sessionStorage的特點會話級別的瀏覽器存儲
大小為5M左右
僅在客戶端使用,不和服務(wù)端進行通信
接口封裝較好
基于上面的特點,sessionStorage 可以有效對表單信息進行維護,比如刷新時,表單信息不丟失。
2.使用場景sessionStorage 更適合用來存儲生命周期和它同步的會話級別的信息。這些信息只適用于當前會話,當你開啟新的會話時,它也需要相應(yīng)的更新或釋放。比如微博的 sessionStorage就主要是存儲你本次會話的瀏覽足跡:
lasturl 對應(yīng)的就是你上一次訪問的 URL 地址,這個地址是即時的。當你切換 URL 時,它隨之更新,當你關(guān)閉頁面時,留著它也確實沒有什么意義了,干脆釋放吧。這樣的數(shù)據(jù)用 sessionStorage 來處理再合適不過。
3.sessionStorage 、localStorage 和 cookie 之間的區(qū)別共同點:都是保存在瀏覽器端,且都遵循同源策略。
不同點:在于生命周期與作用域的不同
作用域:localStorage只要在相同的協(xié)議、相同的主機名、相同的端口下,就能讀取/修改到同一份localStorage數(shù)據(jù)。sessionStorage比localStorage更嚴苛一點,除了協(xié)議、主機名、端口外,還要求在同一窗口(也就是瀏覽器的標簽頁)下
生命周期:localStorage 是持久化的本地存儲,存儲在其中的數(shù)據(jù)是永遠不會過期的,使其消失的唯一辦法是手動刪除;而 sessionStorage 是臨時性的本地存儲,它是會話級別的存儲,當會話結(jié)束(頁面被關(guān)閉)時,存儲內(nèi)容也隨之被釋放。
Web Storage 是一個從定義到使用都非常簡單的東西。它使用鍵值對的形式進行存儲,這種模式有點類似于對象,卻甚至連對象都不是——它只能存儲字符串,要想得到對象,我們還需要先對字符串進行一輪解析。
說到底,Web Storage 是對 Cookie 的拓展,它只能用于存儲少量的簡單數(shù)據(jù)。當遇到大規(guī)模的、結(jié)構(gòu)復(fù)雜的數(shù)據(jù)時,Web Storage 也愛莫能助了。這時候我們就要清楚我們的終極大 boss——IndexedDB!
四、IndexedDBIndexedDB 是一種低級API,用于客戶端存儲大量結(jié)構(gòu)化數(shù)據(jù)(包括文件和blobs)。該API使用索引來實現(xiàn)對該數(shù)據(jù)的高性能搜索。IndexedDB 是一個運行在瀏覽器上的非關(guān)系型數(shù)據(jù)庫。既然是數(shù)據(jù)庫了,那就不是 5M、10M 這樣小打小鬧級別了。理論上來說,IndexedDB 是沒有存儲上限的(一般來說不會小于 250M)。它不僅可以存儲字符串,還可以存儲二進制數(shù)據(jù)。
1.IndexedDB的特點鍵值對儲存。
IndexedDB 內(nèi)部采用對象倉庫(object store)存放數(shù)據(jù)。所有類型的數(shù)據(jù)都可以直接存入,包括 JavaScript 對象。對象倉庫中,數(shù)據(jù)以"鍵值對"的形式保存,每一個數(shù)據(jù)記錄都有對應(yīng)的主鍵,主鍵是獨一無二的,不能有重復(fù),否則會拋出一個錯誤。
異步
IndexedDB 操作時不會鎖死瀏覽器,用戶依然可以進行其他操作,這與 LocalStorage 形成對比,后者的操作是同步的。異步設(shè)計是為了防止大量數(shù)據(jù)的讀寫,拖慢網(wǎng)頁的表現(xiàn)。
支持事務(wù)。
IndexedDB 支持事務(wù)(transaction),這意味著一系列操作步驟之中,只要有一步失敗,整個事務(wù)就都取消,數(shù)據(jù)庫回滾到事務(wù)發(fā)生之前的狀態(tài),不存在只改寫一部分數(shù)據(jù)的情況。
同源限制
IndexedDB 受到同源限制,每一個數(shù)據(jù)庫對應(yīng)創(chuàng)建它的域名。網(wǎng)頁只能訪問自身域名下的數(shù)據(jù)庫,而不能訪問跨域的數(shù)據(jù)庫。
儲存空間大
IndexedDB 的儲存空間比 LocalStorage 大得多,一般來說不少于 250MB,甚至沒有上限。
支持二進制儲存。
IndexedDB 不僅可以儲存字符串,還可以儲存二進制數(shù)據(jù)(ArrayBuffer 對象和 Blob 對象)。
2.IndexedDB的常見操作在IndexedDB大部分操作并不是我們常用的調(diào)用方法,返回結(jié)果的模式,而是請求——響應(yīng)的模式。
建立打開IndexedDB ----window.indexedDB.open("testDB")
這條指令并不會返回一個DB對象的句柄,我們得到的是一個IDBOpenDBRequest對象,而我們希望得到的DB對象在其result屬性中
除了result,IDBOpenDBRequest接口定義了幾個重要屬性:
onerror: 請求失敗的回調(diào)函數(shù)句柄
onsuccess:請求成功的回調(diào)函數(shù)句柄
onupgradeneeded:請求數(shù)據(jù)庫版本變化句柄
控制臺得到一個 IDBDatabase對象,這就是IndexedDB對象
關(guān)閉IndexedDB----indexdb.close()
function closeDB(db){ db.close(); }
刪除IndexedDB----window.indexedDB.deleteDatabase(indexdb)
function deleteDB(name) { indexedDB.deleteDatabase(name) }3.WebStorage、cookie 和 IndexedDB之間的區(qū)別
從上表可以看到,cookie 已經(jīng)不建議用于存儲。如果沒有大量數(shù)據(jù)存儲需求的話,可以使用 localStorage 和 sessionStorage 。對于不怎么改變的數(shù)據(jù)盡量使用 localStorage 存儲,否則可以用 sessionStorage 存儲。
正是瀏覽器存儲、緩存技術(shù)的出現(xiàn)和發(fā)展,為我們的前端應(yīng)用帶來了無限的轉(zhuǎn)機。近年來基于存儲、緩存技術(shù)的第三方庫層出不絕,此外還衍生出了 PWA 這樣優(yōu)秀的 Web 應(yīng)用模型??偨Y(jié)下本文幾個核心觀點:
Cookie 的本職工作并非本地存儲,而是“維持狀態(tài)”
Web Storage 是 HTML5 專門為瀏覽器存儲而提供的數(shù)據(jù)存儲機制,不與服務(wù)端發(fā)生通信
IndexedDB 用于客戶端存儲大量結(jié)構(gòu)化數(shù)據(jù)
給大家推薦一個好用的BUG監(jiān)控工具Fundebug,歡迎免費試用!
歡迎關(guān)注公眾號:前端工匠,你的成長我們一起見證!
優(yōu)質(zhì)交流群 | 微信公眾號 |
---|---|
把cookie聊清楚
HTML5本地存儲——IndexedDB(一:基本使用)
詳說 Cookie, LocalStorage 與 SessionStorage
前端性能優(yōu)化原理與實踐
localstorage 必知必會
瀏覽器數(shù)據(jù)庫 IndexedDB 入門教程
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/103167.html
摘要:摘要以下總結(jié)的跨文檔通信方法,均是在服務(wù)器不參與的情況下服務(wù)端無需特殊的代碼實現(xiàn)的這里的通信,是指頁面向頁面?zhèn)鬟f信息大致分為以下三類通過實現(xiàn)雙向通信通過客戶端存儲實現(xiàn)通信在頁面跳轉(zhuǎn)的過程中攜帶信息中其中第一種方法沒有跨域的限制,且實現(xiàn)的是雙 摘要 以下總結(jié)的跨文檔通信方法,均是在服務(wù)器不參與的情況下(服務(wù)端無需特殊的代碼)實現(xiàn)的 這里的通信,是指頁面A向頁面B傳遞信息 大致分為以下三類...
摘要:維護瀏覽器和服務(wù)器端會話狀態(tài)的一種方式,一般用于保存用戶身份信息。服務(wù)器端生成推送到瀏覽器端,瀏覽器負責(zé)保存和維護數(shù)據(jù)。 Cookie 維護瀏覽器和服務(wù)器端會話狀態(tài)的一種方式,一般用于保存用戶身份信息。 服務(wù)器端生成Cookie推送到瀏覽器端,瀏覽器負責(zé)保存和維護數(shù)據(jù)。 特點 域名下的所用請求都會帶上Cookie 每條Cookie限制在4KB左右 Cookie在過期時間之前一直有效,若...
摘要:如圖圖顧名思義,,是級別的存儲。如筆者寫的一篇淺析文章聊一聊百度移動端首頁前端速度那些事兒讀者們可以嘗試使用。 歡迎大家收看聊一聊系列,這一套系列文章,可以幫助前端工程師們了解前端的方方面面(不僅僅是代碼):https://segmentfault.com/blog/frontenddriver 在web開發(fā)越來越復(fù)雜的今天,前端擁有的能力也越來越多。其中最重要的一項莫過于web存儲。...
閱讀 2061·2023-04-25 16:19
閱讀 3159·2021-11-24 09:39
閱讀 867·2021-11-16 11:44
閱讀 1713·2019-08-29 12:52
閱讀 1163·2019-08-26 13:33
閱讀 1102·2019-08-26 10:26
閱讀 2232·2019-08-23 16:42
閱讀 2619·2019-08-23 14:37