使用 Web Storage API
Web Storage API 提供了瀏覽器安全儲存鍵/值對的機制。
本文將介紹如何使用這項技術。
基本概念
Storage 物件是簡單的鍵/值儲存,類似於物件,但它們在頁面載入之間保持不變。鍵和值始終是字串(請注意,與物件一樣,整數鍵會自動轉換為字串)。你可以像訪問物件一樣訪問這些值,或者使用 Storage.getItem() 和 Storage.setItem() 方法。這三行程式碼都設定了(相同的)colorSetting 條目。
localStorage.colorSetting = "#a4509b";
localStorage["colorSetting"] = "#a4509b";
localStorage.setItem("colorSetting", "#a4509b");
注意: 建議使用 Web Storage API(setItem、getItem、removeItem、key、length)來避免使用普通物件作為鍵/值儲存所帶來的 陷阱。
Web Storage 中的兩種機制如下:
sessionStorage為每個給定的源維護一個單獨的儲存區域,該區域在頁面會話期間(只要瀏覽器開啟,包括頁面重新載入和恢復)可用。localStorage執行相同的功能,但在瀏覽器關閉和重新開啟後仍會持久化。
這些機制可以透過 Window.sessionStorage 和 Window.localStorage 屬性訪問(更準確地說,在支援的瀏覽器中,Window 物件實現了 WindowLocalStorage 和 WindowSessionStorage 物件,而 localStorage 和 sessionStorage 屬性是這些物件的成員)——呼叫其中一個將建立一個 Storage 物件例項,透過該例項可以設定、檢索和刪除資料項。對於每個源的 sessionStorage 和 localStorage 會使用不同的 Storage 物件——它們的功能和控制是分開的。
因此,例如,最初在文件上呼叫 localStorage 將返回一個 Storage 物件;在文件上呼叫 sessionStorage 將返回一個不同的 Storage 物件。兩者都可以用相同的方式進行操作,但彼此獨立。
檢測 localStorage 的支援情況
要能夠使用 localStorage,我們應該首先驗證它是否在當前瀏覽會話中受支援且可用。
測試可用性
支援 localStorage 的瀏覽器在 window 物件上有一個名為 localStorage 的屬性。但是,僅僅測試屬性是否存在,就像在正常的特性檢測中一樣,可能不足夠。各種瀏覽器提供了停用儲存 API 的設定,而不會隱藏全域性物件。因此,瀏覽器可能支援 localStorage,但不向頁面上的指令碼提供它。
例如,對於在瀏覽器隱私瀏覽模式下檢視的文件,某些瀏覽器可能會提供一個配額為零的空 localStorage 物件,實際上使其無法使用。反之,我們也可能會收到一個合法的 QuotaExceededError,這意味著我們已經用完了所有可用的儲存空間,但儲存確實可用。我們的特性檢測應該考慮到這些情況。
這是一個檢測 localStorage 是否被支援且可用的函式:
function storageAvailable(type) {
let storage;
try {
storage = window[type];
const x = "__storage_test__";
storage.setItem(x, x);
storage.removeItem(x);
return true;
} catch (e) {
return (
e instanceof DOMException &&
e.name === "QuotaExceededError" &&
// acknowledge QuotaExceededError only if there's something already stored
storage &&
storage.length !== 0
);
}
}
以下是如何使用它:
if (storageAvailable("localStorage")) {
// Yippee! We can use localStorage awesomeness
} else {
// Too bad, no localStorage for us
}
你可以透過呼叫 storageAvailable("sessionStorage") 來改用 sessionStorage 進行測試。
示例
為了說明一些典型的 Web Storage 用法,我們建立了一個名為“Web Storage Demo”的示例。該 主頁 提供了用於自定義顏色、字型和裝飾影像的控制元件。

當您選擇不同的選項時,頁面會立即更新;此外,您的選擇會儲存在 localStorage 中,因此當您離開頁面並稍後重新載入它時,您的選擇會被記住。
我們還提供了一個 事件輸出頁面 — 如果您在另一個標籤頁中載入此頁面,然後更改主頁中的選擇,您將看到更新的儲存資訊作為 StorageEvent 觸發的輸出。

注意: 除了透過上面的連結即時檢視示例頁面外,您還可以 檢視原始碼。
測試您的儲存是否已填充
首先,在 main.js 中,我們測試儲存物件是否已填充(即,頁面之前已被訪問)。
if (!localStorage.getItem("bgcolor")) {
populateStorage();
} else {
setStyles();
}
Storage.getItem() 方法用於從儲存中獲取資料項;在這種情況下,我們正在測試 bgcolor 項是否存在;如果不存在,我們執行 populateStorage() 將現有的自定義值新增到儲存中。如果已經存在值,我們執行 setStyles() 以儲存的值更新頁面樣式。
注意: 您也可以使用 Storage.length 來測試儲存物件是否為空。
從儲存中獲取值
如上所述,可以使用 Storage.getItem() 從儲存中檢索值。它以資料項的鍵作為引數,並返回資料值。
例如
function setStyles() {
const currentColor = localStorage.getItem("bgcolor");
const currentFont = localStorage.getItem("font");
const currentImage = localStorage.getItem("image");
document.getElementById("bgcolor").value = currentColor;
document.getElementById("font").value = currentFont;
document.getElementById("image").value = currentImage;
htmlElem.style.backgroundColor = `#${currentColor}`;
pElem.style.fontFamily = currentFont;
imgElem.setAttribute("src", currentImage);
}
這裡,前三行從本地儲存中獲取值。接下來,我們將表單元素中顯示的值設定為這些值,以便在重新載入頁面時保持同步。最後,我們更新頁面上的樣式/裝飾影像,以便在重新載入時再次顯示您的自定義選項。
將值設定到儲存中
Storage.setItem() 用於建立新資料項,以及(如果資料項已存在)更新現有值。它接受兩個引數——要建立/修改的資料項的鍵,以及要儲存的值。
function populateStorage() {
localStorage.setItem("bgcolor", document.getElementById("bgcolor").value);
localStorage.setItem("font", document.getElementById("font").value);
localStorage.setItem("image", document.getElementById("image").value);
setStyles();
}
populateStorage() 函式在本地儲存中設定三個項——背景顏色、字型和影像路徑。然後它執行 setStyles() 函式來更新頁面樣式等。
我們還在每個表單元素上包含了一個 onchange 處理程式,以便在更改表單值時更新資料和樣式。
bgcolorForm.onchange = populateStorage;
fontForm.onchange = populateStorage;
imageForm.onchange = populateStorage;
Storage 只支援儲存和檢索字串。如果你想儲存其他資料型別,你必須將它們轉換為字串。對於普通物件和陣列,可以使用 JSON.stringify()。
const person = { name: "Alex" };
localStorage.setItem("user", person);
console.log(localStorage.getItem("user")); // "[object Object]"; not useful!
localStorage.setItem("user", JSON.stringify(person));
console.log(JSON.parse(localStorage.getItem("user"))); // { name: "Alex" }
然而,沒有通用的方法可以儲存任意資料型別。此外,檢索到的物件是原始物件的深複製,對它的修改不會影響原始物件。
使用 StorageEvent 響應儲存更改
當共享相同儲存空間的另一個文件的 Storage 物件發生更改時,將觸發 storage 事件。這在進行更改的同一頁面上不起作用——它實際上是一種讓使用該儲存的其他頁面同步所做更改的方式。其他來源的頁面無法訪問相同的儲存物件。
對於 localStorage,儲存空間由同一來源的所有選項卡共享。對於 sessionStorage,儲存空間僅在選項卡內共享, among all iframes from the same origin(在同一來源的所有 iframe 之間共享)。
在事件頁面(參見 events.js)上,唯一的 JavaScript 如下:
window.addEventListener("storage", (e) => {
document.querySelector(".my-key").textContent = e.key;
document.querySelector(".my-old").textContent = e.oldValue;
document.querySelector(".my-new").textContent = e.newValue;
document.querySelector(".my-url").textContent = e.url;
document.querySelector(".my-storage").textContent = JSON.stringify(
e.storageArea,
);
});
這裡我們向 window 物件添加了一個事件監聽器,當與當前來源相關的 Storage 物件發生更改時觸發。如上所示,與此事件關聯的事件物件具有許多包含有用資訊的屬性——更改的資料的鍵,更改前的值,更改後的新值,更改儲存的文件的 URL,以及儲存物件本身(我們已將其字串化,以便您可以看到其內容)。
刪除資料記錄
Web Storage 還提供了一些簡單的刪除資料的方法。我們在演示中沒有使用它們,但將它們新增到您的專案中非常簡單。
Storage.removeItem()接受一個引數——您要刪除的資料項的鍵——並將其從該來源的儲存物件中刪除。Storage.clear()不接受任何引數,並清空該來源的整個儲存物件。
規範
| 規範 |
|---|
| HTML # dom-localstorage-dev |
| HTML # dom-sessionstorage-dev |
瀏覽器相容性
api.Window.localStorage
載入中…
api.Window.sessionStorage
載入中…