揭祕前端儲存

Reaper622發表於2019-04-09

最近在專案中使用了部分的前端儲存,之前只有一些簡單的瞭解,今天就趁這個機會把前端儲存進行深入研究一番。

寫在開始

前端儲存的好處:

  • 方便網頁的載入,避免了在傳送請求收到響應前頁面的空白期。
  • 也可以在非強制性要求實時最新資料時減少向服務端的請求,加快渲染速度。
  • 在網路不佳或無網路時仍有離線資料可以檢視。

前端儲存的方式:

首先我們應該先清除大概都有哪些儲存方式,對此我們只需要開啟控制檯,選擇 application 來進行檢視。

A5HpRI.jpg

我們可以看到,儲存大概分為兩大類,一類為 儲存類 ,另一類為 快取類

儲存類:
  • 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 之後進入控制檯檢視一下

AIgIEt.jpg

  • 名稱
  • 路徑
  • 失效時間 (格林威治時間)
  • 大小
  • 是否為 HTTP請求
  • 安全性

域 路徑 失效時間 和 安全性 都是伺服器給瀏覽器的指示,他們不會隨著請求傳送給伺服器,傳送給伺服器的只有名稱與值對。

Cookie 的限制性

  • 如果設定了 Cookie 的過期時間,那麼 Cookie 會在到期時自動失效。
  • 如果沒有設定過期時間,那麼 Cookie 就是 session 級別的,即瀏覽器關閉時 Cookie 自動消失。

Cookie 的優缺點

優點:

1. 可以控制過期時間,不會永久有效,有一定的安全保障。
2. 可進行擴充套件,可跨域共享。
3. 通過加密與安全傳輸技術 (SSL) ,可以減少 Cookie 被破解的可能性。
4. 有較高的相容性。
複製程式碼

缺點:

1. 有一定的數量與長度限制,每個 Cookie 長度不能超過 4 KB ,否則超出部分會被截掉。
2. 請求頭上的資料容易被攔截攻擊。
複製程式碼

新生力量 Web Storage

LocalStorage 與 SessionStorage

我們可以先看一下它的相容性,許多瀏覽器已經完全支援了它:

AIW1HA.md.jpg
AIWlBd.md.jpg

資料來源: MDN

出現原因

  • 克服 Cookie 的一些限制,同時儲存一些需要嚴格控制在客戶端,不需要傳送給伺服器的一些資料。
  • 提供了除 Cookie 之外的另一種儲存會話的途徑。
  • 提供了一種大容量儲存空間來跨回話儲存資料的途徑。

如何檢視

它們都是直接作為 window物件的屬性存在的,我們可以直接通過 window.localStoragewindow.sessionStorage 來訪問。

AIf7Zj.jpg

同時,我們觀察到 Web Storage 只能儲存字串,如果用 Web Storage 儲存物件,會出現 [Object Object], 可以用 JSON.stringifyJSON.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

本地儲存與離線儲存

前端儲存之IndexDB

相關文章