最近在專案中使用了部分的前端儲存,之前只有一些簡單的瞭解,今天就趁這個機會把前端儲存進行深入研究一番。
寫在開始
前端儲存的好處:
- 方便網頁的載入,避免了在傳送請求收到響應前頁面的空白期。
- 也可以在非強制性要求實時最新資料時減少向服務端的請求,加快渲染速度。
- 在網路不佳或無網路時仍有離線資料可以檢視。
前端儲存的方式:
首先我們應該先清除大概都有哪些儲存方式,對此我們只需要開啟控制檯,選擇 application 來進行檢視。
我們可以看到,儲存大概分為兩大類,一類為 儲存類 ,另一類為 快取類。
儲存類:
-
Web儲存 (Web Storage):HTML 5 中提出的儲存方式,容量有 5 M。
- localStorage
- sessionStorage
-
Cookie:瀏覽器普遍支援的基於 HTTP 協議的儲存方式,但容量只有 4 KB
-
資料庫儲存:
- IndexDB
- Web SQL
快取類:
- Cache Storage: 在 Service Worker 的規範中提出,一般配合 Service Worker 進行離線快取。
- Application Cache: 在 HTML5.1提出的快取方式,可用來構建離線應用。
介紹
個子小的長兄 —— Cookie
HTTP Cookie,它最初適用於客戶端儲存會話資訊的、這個標準要求伺服器對 HTTP 請求設定 Set-Cookie HTTP 頭作為響應的一部分,其中會包含有會話資訊。瀏覽器在 Cookie 中儲存繪畫資訊,並在傳送請求時將 Cookie 一起傳送過去。
Cookie 的構成
我們先開啟 github 之後進入控制檯檢視一下
- 名稱
- 值
- 域
- 路徑
- 失效時間 (格林威治時間)
- 大小
- 是否為 HTTP請求
- 安全性
域 路徑 失效時間 和 安全性 都是伺服器給瀏覽器的指示,他們不會隨著請求傳送給伺服器,傳送給伺服器的只有名稱與值對。
Cookie 的限制性
- 如果設定了 Cookie 的過期時間,那麼 Cookie 會在到期時自動失效。
- 如果沒有設定過期時間,那麼 Cookie 就是 session 級別的,即瀏覽器關閉時 Cookie 自動消失。
Cookie 的優缺點
優點:
1. 可以控制過期時間,不會永久有效,有一定的安全保障。
2. 可進行擴充套件,可跨域共享。
3. 通過加密與安全傳輸技術 (SSL) ,可以減少 Cookie 被破解的可能性。
4. 有較高的相容性。
複製程式碼
缺點:
1. 有一定的數量與長度限制,每個 Cookie 長度不能超過 4 KB ,否則超出部分會被截掉。
2. 請求頭上的資料容易被攔截攻擊。
複製程式碼
新生力量 Web Storage
LocalStorage 與 SessionStorage
我們可以先看一下它的相容性,許多瀏覽器已經完全支援了它:
出現原因
- 克服 Cookie 的一些限制,同時儲存一些需要嚴格控制在客戶端,不需要傳送給伺服器的一些資料。
- 提供了除 Cookie 之外的另一種儲存會話的途徑。
- 提供了一種大容量儲存空間來跨回話儲存資料的途徑。
如何檢視
它們都是直接作為 window
物件的屬性存在的,我們可以直接通過 window.localStorage
與 window.sessionStorage
來訪問。
同時,我們觀察到 Web Storage 只能儲存字串,如果用 Web Storage 儲存物件,會出現
[Object Object]
, 可以用JSON.stringify
與JSON.parse
方法來解決這個問題。
Web Storage 例項方法
- clear:刪除所有值
- getItem(name): 根據傳入的鍵來獲取對應的值。
- key(index): 獲得所對應索引的鍵,名稱。
- removeItem(name): 刪除鍵對應的鍵值對
- setItem(name, value): 為指定的 name 設定一個對應的值。
沒有感情的 sessionStorage
- 同源策略: 不同於 Cookie, sessionStorage 訪問限制更高,只有當前設定了 sessionStorage 的域下才能訪問。
- 單標籤頁: 兩個相同域下的標籤頁不能互通。
- 在關閉標籤頁或者新開的標籤頁下都不能訪問之前寫下的 sessionStorage
- 重新整理標籤頁依然可以訪問 sessionStorage
使用的場景:
1. 主要針對會話級的小資料的儲存。
2. 儲存一些在當前頁面重新整理仍然需要儲存,但是關閉後不需要留下的資訊。
3. 很適合單頁應用的使用,可以用來儲存登入態資訊等。
複製程式碼
不離不棄的 localStorage
- 同源策略:和 sessionStorage 一樣,要訪問同一個 localStorage 頁面必須來自同一個域名,同種協議,同種埠。
- localStorage 設定後,重新整理或者重新開啟標籤頁,關閉瀏覽器重新開啟原來的標籤頁也可以訪問到。
使用的場景:
1. 永續性的儲存客戶端資料,只能通過 JavaScript 刪除或者使用者清除瀏覽器快取。
2. 如果有一些稍大量的資料,例如編輯器的自動儲存等。
3. 多頁面間訪問共同資料。 sessionStorage 只能用於一個標籤頁,而localStorage可以在多個標籤頁之間共享。
複製程式碼
sessionStorage 與 localStorage 的區別
- 生命週期:localStorage 是本地儲存,沒有期限,只能使用者自己操作來刪除。 sessionStroage 是會話儲存,頁面關閉資料就會丟失。
- sessionStorage 有單標籤頁的限制,localStorage則沒有。
Storage 事件
我們對 Storage 物件進行任何的操作,都會在文件上觸發 Storage 事件, 這個事件的 event 物件有以下屬性:
- domain:發生變化的儲存空間的域名。
- key:設定或刪除的鍵名
- newValue: 如果是設定值,則是新值。如果是刪除鍵,則為null。
- oldValue:鍵被更改之前的值。
資料庫級別: IndexDB 與 Web SQL
Web SQL 類似關係型資料庫, 它使用 sql 語句進行相關操作。
indexDB 類似 NoSQL , 直接使用 js 的方法運算元據。
特點:
- 訪問:indexDB 和 Web SQL 和 Web Storage 一樣,均是隻能在建立資料庫的域名下才能訪問。
- 儲存時間:儲存時間為永久,除非使用者清除資料,他可用作長期的儲存。
- 大小限制:二者其實沒有強制限制。只是 indexDB 在資料超過 50 M 之後會從瀏覽器彈出一個框讓你確認。
- 效能: indexDB 查詢速度會相對較慢,而 Web SQL 的效能相對較快。
實際操作
第一步開啟資料庫
var request = indexedDB.open(name, version);
複製程式碼
第一個引數為資料庫的名稱,第二個引數為資料庫的版本號。
第二步新增資料
建立事務,並加上資料讀寫許可權。
var transaction = db.transaction(storeName, 'readwrite');
複製程式碼
獲取 objectStore 再呼叫add方法新增資料
var store = transaction.objectStore(storeName);
var request = store.get(key);
request.onsuccess = function (e) {
data = e.target.result;
console.log(student.name);
};
複製程式碼
第三步刪除資料
刪除也需要建立事務,呼叫刪除介面 ,通過key刪除物件。
var transaction = db.transaction(storeName, 'readwrite');
var store = transaction.objectStore(storeName);
store.delete(key);
複製程式碼
第四步查詢資料
-
按key查詢
開啟事務,獲取到 objectStore ,呼叫get()方法獲取物件。
var transaction = db.transaction(storeName, 'readwrite'); var store = transaction.objectStore(storeName); var request = store.get(key); request.onsuccess = function (e) { data = e.target.result; console.log(student.name) }; 複製程式碼
-
使用索引查詢
我們在使用索引之前需要先建立索引,它使用
createIndex
方法建立索引,方法有三個引數: 索引名稱、索引屬性欄位名,索引屬性值是否唯一。objectStore.createIndex('name','name', { unique: false }) 複製程式碼
建立好了索引,我們就可以使用索引進行查詢:
var transaction = db.transaction(storeName); var store = transaction.objectStore(storeName); var index = store.index(search_index); index.get(value).onsuccess = function (e) { data = e.target.result; console.log(student.id); } 複製程式碼
-
遊標遍歷資料
var transaction = db.transaction(storeName); var store = transaction.objectStore(storeName); var request = store.openCursor(); //成功開啟遊標 var dataList = new Array(); var i = 0; request.onsuccess = function (e) { var cursor = e.target.result; if (cursor) { console.log(cursor.key); dataList[i] = cursor.value; console.log(dataList[i].name); i++; cursor.continue(); } data = dataList; } 複製程式碼
第五步,更新物件
為了更新物件,我們首先要把它取出來,進行修改之後再放回去。
var transaction = db.transaction(storeName, 'readwrite');
var store = transaction.objectStore(storeName);
var request = store.get(key);
request.onsuccess = function (e) {
var data = e.target.result;
for (a in newData) {
data.a = newData.a;
}
store.put(data);
}
複製程式碼
第六步,關閉與刪除
關閉資料庫需要呼叫資料庫的 close 方法
db.close();
複製程式碼
刪除資料庫使用資料庫物件 deleteDatabase 方法
function deleteDB (name) {
indexedDB.deleteDatabase(name);
}
複製程式碼
IndexDB 特點
- 它的資料儲存在物件儲存空間中。
- 建立物件儲存空間,首先先定義一個鍵,之後新增資料。
- 可以使用遊標查詢。
indexDB 的相容性還是一大問題,Web SQL 雖然過時,但相容性卻仍然非常好,移動端幾乎均可用。
Cache Storage
Cache Storage
是用來儲存 Response
物件 ,也就是對 HTTP 響應進行快取。 Cache Storage
是多個 cache
的集合,每個 cache
可以儲存多個響應物件。它基於 Promise。這裡不做詳細的贅述。
Application Cache
它是 HTML5 中新引入的應用程式換粗技術,它的出現意味著 web 應用可以通過快取,在沒有網路的環境下執行,構建離線應用。
優點:
- 離線瀏覽
- 提升頁面的載入速度
- 降低伺服器的壓力
一般來說 Application Cache
只用來儲存一些靜態資源,它的使用方式主要需要兩個步驟:
1.服務端維護一個 manifest
清單
2.瀏覽器端進行一個設定。
<html manifest="demo">
複製程式碼
一般的,我們必須給 manifest 檔案設定正確的 MIME-type 為 "text/cache-manifest",它需要在伺服器端進行配置。
在 Progressive Web Application 中, Application Cache 配合 Service Worker 承擔著主要的任務。
參考文獻
MDN: LocalStorage , sessionStorage, indexDB