2021年了,你該選擇哪個(gè)瀏覽器存儲(chǔ)選項(xiàng)?
本文轉(zhuǎn)載自公眾號(hào)“讀芯術(shù)”(ID:AI_Discovery)
現(xiàn)代網(wǎng)絡(luò)瀏覽器為網(wǎng)絡(luò)應(yīng)用提供多種存儲(chǔ)選項(xiàng)。每個(gè)存儲(chǔ)選項(xiàng)都不一樣,有各自的屬性和應(yīng)用。然而,若要根據(jù)自身需求選擇合適的存儲(chǔ)選項(xiàng),需要對(duì)它們的屬性和限制有充分的理解。本文將探究5個(gè)瀏覽器儲(chǔ)存選項(xiàng)以及它們的狀況,幫助你找到最適合你需求的那個(gè)。
快速瀏覽一下Chrome開(kāi)發(fā)者工具,會(huì)發(fā)現(xiàn)以下幾種瀏覽器存儲(chǔ)類型:
- Local Storage
- Session Storage
- IndexedDB
- Web SQL
- Cookies
讓我們來(lái)詳細(xì)了解一下每個(gè)存儲(chǔ)選項(xiàng)及其特定屬性。
1.Local Storage
Local Storage是比較廣泛使用的一種存儲(chǔ)方式,因?yàn)楹?jiǎn)單。這種存儲(chǔ)方式允許存儲(chǔ)序列化為字符串的鍵值對(duì)。你可以在Local Storage上執(zhí)行以下操作:
- setItem() — save key-value
- getItem() — get key-value
- removeItem() — remove key-value
- clear() — clear all key-values
- key() — retrieve number nth key-value
要將Local Storage中的值設(shè)置為數(shù)組、對(duì)象等,需要使用JSON.stringify將值轉(zhuǎn)換為字符串。檢索時(shí),JSON.parse將該項(xiàng)重新構(gòu)造回JSON。
- //set key-value pair at local storage as a string
- localStorage.setItem('session', JSON.stringify({'id': 5, 'timeout' :500000}));//get value as an object
- var sessionItem = JSON.parse(localStorage.getItem('session'));
主要亮點(diǎn):
- Local Storage在同一來(lái)源的所有選項(xiàng)卡和窗口之間共享。
- 數(shù)據(jù)不會(huì)過(guò)期。
- 支持存儲(chǔ)事件。
存儲(chǔ)事件是由Local Storage和Session Storage支持的一項(xiàng)功能,它只觸發(fā)其他選項(xiàng)卡(不包括觸發(fā)它的選項(xiàng)卡)和iFrames中的事件偵聽(tīng)器。讓我們仔細(xì)看看存儲(chǔ)事件:
- //Firing storage event by addEventListener
- window.addEventListener('storage', () => {
- console.log(window.localStorage.getItem('id'));
- });
2.SessionStorage
Session Storage與Local Storage類似,唯一的區(qū)別是session storage里的數(shù)據(jù)可以持續(xù)到關(guān)閉瀏覽器選項(xiàng)卡。因此,Session Storage已經(jīng)擴(kuò)展到應(yīng)用程序源和瀏覽器選項(xiàng)卡。
我很好奇存儲(chǔ)事件是如何與Session Storage協(xié)作的。即使有存儲(chǔ)事件,瀏覽器選項(xiàng)卡隔離仍然存在。對(duì)于Session Storage,存儲(chǔ)事件只能通過(guò)同一選項(xiàng)卡中的iFrames進(jìn)行訪問(wèn)。
此外,無(wú)論是Local Storage還是Session Storage,訪問(wèn)都是同步的,你的JavaScript代碼將在訪問(wèn)這些存儲(chǔ)時(shí)一直等到接收到數(shù)據(jù)。
3.IndexedDB
與上述存儲(chǔ)選項(xiàng)相比,IndexedDB與典型的NoSQL數(shù)據(jù)庫(kù)更相近。在處理復(fù)雜的、難以序列化的JavaScript對(duì)象時(shí),可以考慮IndexedDB。IndexedDB還支持事務(wù),同時(shí)與Web Workers協(xié)作良好。
舉個(gè)例子,Twitter使用帶有三個(gè)表的IndexedDB保存數(shù)據(jù)。你可以在數(shù)組中查找最近的搜索,以提高可用性。

主要亮點(diǎn):
- 可以存儲(chǔ)任何JavaScript類型的數(shù)據(jù)作為鍵值對(duì),如對(duì)象(blob,file)或數(shù)組等。
- IndexedDB API是異步的,因此在請(qǐng)求完成時(shí),它會(huì)返回一個(gè)回調(diào)。
- 可以存儲(chǔ)結(jié)構(gòu)化數(shù)據(jù),如日歷數(shù)據(jù)。
4.Web SQL(不推薦)
最近,W3C宣布不推薦使用WebSQL規(guī)范,更好的選擇是高效的indexedDB。Web SQL是遵循SQLite規(guī)范的存儲(chǔ)。谷歌瀏覽器、Opera和安卓瀏覽器都支持這個(gè)API(注意:火狐瀏覽器不支持Web SQL)。
Web SQL中有三種方法,
- openDatabase()——使用現(xiàn)有數(shù)據(jù)庫(kù)創(chuàng)建數(shù)據(jù)庫(kù)或創(chuàng)建新數(shù)據(jù)庫(kù)。
- transaction ()—控制事務(wù)(提交或回滾)。
- executeSql()—可以執(zhí)行真實(shí)的Sql查詢。
- var db =openDatabase(‘testDB’, ‘1.0’, ‘Test DB’, 3* 1024 * 1024);
- db.transaction(function (tr) {
- tr.executeSql(‘CREATE TABLE IF NOTEXISTS TestTable (id unique, data)’);
- tr.executeSql(‘INSERT INTO TestTable(id, data) VALUES (1, “itemOne”)’);
- tr.executeSql(‘INSERT INTO TestTable(id, data) VALUES (2, “itemTwo”)’);
- });

主要亮點(diǎn):
- 與其他存儲(chǔ)選項(xiàng)不同,你可以使用SQL查詢與數(shù)據(jù)庫(kù)進(jìn)行交互。
- 對(duì)于任何熟悉SQLite的人來(lái)說(shuō),學(xué)習(xí)空間很小甚至是沒(méi)有。
5.Cookies
Cookies是唯一一個(gè)也與服務(wù)器共享的瀏覽器存儲(chǔ)選項(xiàng)。兩類Cookies分別是:
- 服務(wù)器端Cookie(僅僅適用于HTTP的Cookie)——由服務(wù)器設(shè)置的變量,存儲(chǔ)在瀏覽器中。用于存儲(chǔ)應(yīng)用程序狀態(tài)。無(wú)法通過(guò)JavaScript訪問(wèn)。
- 客戶端Cookie——與服務(wù)器端Cookie類似,但是可以通過(guò)JavaScript訪問(wèn)。
- //Initialize a cookie
- document.cookie = “username=Charuka Herath; expires=Thu, 31 Dec 2020 12:00:00UTC; path=/”;//Read a cookie
- var cookie= document.cookie;//Remove cookie (Set expiration date to a pastdate)
- document.cookie = "username=; expires=Thu, 31 Dec 2019 12:00:00 UTC;path=/";
值得注意的是,對(duì)于每個(gè)請(qǐng)求,瀏覽器都會(huì)向服務(wù)器返回Cookies。因此,需要將它們最小化,以減少開(kāi)銷(xiāo)。
主要亮點(diǎn):
- 高效地恢復(fù)會(huì)話、頁(yè)面細(xì)節(jié)、網(wǎng)頁(yè)線程。
- Cookies會(huì)持續(xù)存在。因此,數(shù)據(jù)可以保存在瀏覽器中,直到它們被清除。
- 可以根據(jù)特定用戶的偏好進(jìn)行管理并提供個(gè)性化內(nèi)容。
- 支持帶通配符的跨來(lái)源。

就安全性而言,這些存儲(chǔ)選項(xiàng)不是為了存儲(chǔ)敏感數(shù)據(jù)而設(shè)計(jì)的。但是,在Local Storage(由受歡迎的JavaScript庫(kù)支持,這些庫(kù)是開(kāi)放的,可以進(jìn)行解釋)中存儲(chǔ)身份驗(yàn)證令牌(OpenID令牌)的趨勢(shì)越來(lái)越明顯。Cookie在保留會(huì)話標(biāo)識(shí)符方面有一個(gè)例外,這是專門(mén)為其存儲(chǔ)而設(shè)計(jì)的。
此外,需要注意的是,Safari中的私人瀏覽(匿名)不允許用戶訪問(wèn)Local Storage或Session Storage。因此,如果你繼續(xù)使用這些存儲(chǔ)選項(xiàng),處理錯(cuò)誤情況并向用戶顯示相關(guān)消息是非常重要的。
選擇存儲(chǔ)選項(xiàng)時(shí),如果只需存儲(chǔ)簡(jiǎn)單的鍵值對(duì),Local Storage是不錯(cuò)的選擇。如果你計(jì)劃對(duì)瀏覽器選項(xiàng)卡確定稍微好一點(diǎn)的安全范圍,可以選擇Session Storage。在選擇這兩個(gè)選項(xiàng)之前,請(qǐng)記住存儲(chǔ)限制。
對(duì)于任何高級(jí)存儲(chǔ)需求,你都可以使用IndexedDB,這是一種更好的數(shù)據(jù)庫(kù)解決方案。