前端本地存儲(Cookie、LocalStorage、SessionStorage)

在前端開發中,本地存儲用於在瀏覽器中持久化或臨時存儲數據,常見場景包括保存用户登錄狀態、記住用户偏好、緩存臨時數據等(如小米官網手機端頭部廣告的 “關閉後不再顯示” 功能)。本文將詳細梳理 CookieLocalStorageSessionStorage 及輔助工具庫的用法與區別。

一、Cookie:傳統會話存儲方案

Cookie 是最早的前端本地存儲技術,主要用於在客户端與服務器之間傳遞會話信息(如用户登錄狀態),是 HTTP 協議的一部分。

1. Cookie 的核心概念

  • 定義:Cookie 是服務器發送給瀏覽器的小型文本文件,瀏覽器會將其保存在本地,後續請求同一服務器時會自動攜帶 Cookie。
  • 作用:實現 “會話跟蹤”(如記住登錄狀態、購物車信息),解決 HTTP 協議 “無狀態” 的問題。
  • 特點
  • 存儲容量小:僅 4KB,只能存儲文本字符串。
  • 數量限制:不同瀏覽器限制不同(IE6 最多 20 條,現代瀏覽器約 50 條)。
  • 會隨請求發送:每次請求同一域名時,Cookie 會自動附加在 HTTP 頭中,可能增加帶寬消耗。
  • 安全性較低:數據明文存儲(可加密),可能被劫持或篡改。

2. Cookie 的基本操作(原生 JS)

Cookie 的操作通過 document.cookie 實現,需手動處理格式(鍵值對 + 可選屬性)。

(1)設置 Cookie

語法:document.cookie = "key=value; [expires=日期; path=路徑; domain=域名; secure]"

  • expires:過期時間(GMT 格式字符串,不設置則為 “會話級”,關閉瀏覽器失效)。
  • path:Cookie 生效的路徑(默認當前頁面路徑,path=/ 表示全站生效)。
  • domain:Cookie 生效的域名(默認當前域名,子域名需單獨設置)。
  • secure:僅在 HTTPS 協議下傳輸(默認不開啓)。

示例:設置 “2 天后過期、全站生效” 的 Cookie

javascript

運行

// 計算過期時間(2 天后)
const expires = new Date();
expires.setTime(expires.getTime() + 2 * 24 * 60 * 60 * 1000); // 毫秒級計算

// 設置 Cookie(escape 處理特殊字符,如中文)
document.cookie = `username=${escape("張三")}; expires=${expires.toGMTString()}; path=/`;
(2)獲取 Cookie

document.cookie 會返回所有生效的 Cookie(以 分隔的鍵值對字符串),需手動解析:

javascript

運行

function getCookie(key) {
  const cookieStr = document.cookie;
  const cookieArr = cookieStr.split("; "); // 分割為鍵值對數組
  
  for (let i = 0; i < cookieArr.length; i++) {
    const [currentKey, currentValue] = cookieArr[i].split("=");
    if (currentKey === key) {
      return unescape(currentValue); // 解碼特殊字符
    }
  }
  return null; // 未找到對應 Cookie
}

// 使用
console.log(getCookie("username")); // 輸出:張三
(3)修改 Cookie

修改 Cookie 只需重新設置同名 Cookie(覆蓋原有值),注意 path、domain 需與原 Cookie 一致

javascript

運行

const expires = new Date();
expires.setTime(expires.getTime() + 3 * 24 * 60 * 60 * 1000); // 延長至 3 天過期
document.cookie = `username=${escape("李四")}; expires=${expires.toGMTString()}; path=/`;
(4)刪除 Cookie

刪除 Cookie 需將 expires 設置為 “過去的時間”(讓 Cookie 立即過期):

javascript

運行

function deleteCookie(key) {
  const expires = new Date(0); // 1970-01-01 00:00:00(過去的時間)
  document.cookie = `${key}=; expires=${expires.toGMTString()}; path=/`;
}

// 使用
deleteCookie("username");

3. Cookie 工具庫:js-cookie

原生 Cookie 操作繁瑣,推薦使用第三方庫 js-cookie 簡化開發,支持 npm 安裝或 CDN 引入。

(1)引入方式
  • CDN 引入(快速開發): html
    預覽
<script src="https://cdn.bootcdn.net/ajax/libs/js-cookie/3.0.5/js.cookie.js"></script>
  • npm 安裝(工程化項目): bash
npm install js-cookie --save
(2)核心用法

操作

代碼示例

説明

設置 Cookie

Cookies.set("key", "value", { expires: 7 })

expires:7 表示 7 天后過期,默認會話級

讀取 Cookie

Cookies.get("key")

讀取單個 Cookie;Cookies.get() 讀取所有

讀取 JSON

Cookies.getJSON("user")

直接解析存儲的 JSON 字符串為對象

刪除 Cookie

Cookies.remove("key", { path: "/" })

需與設置時的 path/domain 一致

示例:存儲用户信息(對象)

javascript

運行

// 存儲對象(需先轉為 JSON 字符串)
const user = { name: "張三", age: 20 };
Cookies.set("user", JSON.stringify(user), { expires: 7, path: "/" });

// 讀取並解析對象
const storedUser = JSON.parse(Cookies.get("user"));
// 或直接用 getJSON
const storedUser = Cookies.getJSON("user");
console.log(storedUser.name); // 輸出:張三

// 刪除
Cookies.remove("user", { path: "/" });

二、LocalStorage:HTML5 永久本地存儲

LocalStorage 是 HTML5 引入的本地存儲方案,專門用於在客户端持久化存儲數據,不與服務器交互。

1. LocalStorage 的核心特點

  • 存儲容量:約 5MB(遠大於 Cookie),僅存儲文本字符串。
  • 生命週期永久存儲,除非手動刪除(清除瀏覽器數據或代碼刪除)。
  • 作用域:遵循 “同源策略”(同一協議、域名、端口),不同域名數據不共享。
  • 前端專屬:僅前端可操作,不會隨 HTTP 請求發送給服務器,安全性高於 Cookie。
  • 兼容性:支持 IE8+ 及所有現代瀏覽器。

2. LocalStorage 的基本操作

LocalStorage 提供簡潔的 API,無需手動解析格式,核心方法為 setItemgetItemremoveItemclear

(1)兼容性判斷

使用前建議判斷瀏覽器是否支持:

javascript

運行

if (!window.localStorage) {
  alert("您的瀏覽器不支持 LocalStorage,請升級!");
} else {
  // 執行 LocalStorage 操作
}
(2)核心操作

操作

代碼示例

説明

設置數據

localStorage.setItem("key", "value")

或 localStorage.key = "value",自動轉字符串

讀取數據

localStorage.getItem("key")

或 localStorage.key,不存在返回 null

修改數據

localStorage.setItem("key", "newValue")

覆蓋原有值(鍵名相同)

刪除單個數據

localStorage.removeItem("key")

刪除指定鍵的數據

清空所有數據

localStorage.clear()

清空當前域名下所有 LocalStorage 數據

示例:實現 “廣告關閉後不再顯示”(小米官網廣告場景)

html

預覽

<!-- HTML:頂部廣告 -->
<div class="header-ad">
  <img src="ad.jpg" alt="廣告">
  <span class="close-btn">×</span>
</div>

<!-- CSS:隱藏廣告的樣式 -->
<style>
  .header-ad { display: block; width: 100%; height: 80px; }
  .header-ad.hidden { display: none; }
  .close-btn { float: right; cursor: pointer; }
</style>

<!-- JS:LocalStorage 控制顯示/隱藏 -->
<script>
  // 頁面加載時判斷:是否已關閉過廣告
  const ad = document.querySelector(".header-ad");
  if (localStorage.getItem("adClosed")) {
    ad.classList.add("hidden"); // 已關閉,隱藏廣告
  }

  // 點擊關閉按鈕:隱藏廣告並記錄狀態
  document.querySelector(".close-btn").addEventListener("click", () => {
    ad.classList.add("hidden");
    localStorage.setItem("adClosed", "true"); // 存儲“已關閉”狀態
  });
</script>
(3)存儲對象 / 數組

LocalStorage 僅支持字符串,存儲對象 / 數組需通過 JSON.stringify 轉為字符串,讀取時用 JSON.parse 解析:

javascript

運行

// 存儲數組
const movies = ["《奪冠》", "《隱秘的角落》"];
localStorage.setItem("movies", JSON.stringify(movies));

// 讀取並解析數組
const storedMovies = JSON.parse(localStorage.getItem("movies"));
console.log(storedMovies[0]); // 輸出:《奪冠》

// 存儲對象
const user = { name: "李四", age: 22 };
localStorage.setItem("user", JSON.stringify(user));

// 讀取並解析對象
const storedUser = JSON.parse(localStorage.getItem("user"));
console.log(storedUser.age); // 輸出:22

3. LocalStorage 的侷限

  • 僅支持字符串存儲,複雜數據需手動 JSON 轉換。
  • 永久存儲可能佔用瀏覽器空間,需合理清理過期數據。
  • 隱私模式下可能不可用(部分瀏覽器隱私模式會禁用 LocalStorage)。
  • 數據不會自動同步,多標籤頁修改需手動處理同步邏輯。

三、SessionStorage:HTML5 會話級本地存儲

SessionStorage 與 LocalStorage 用法完全一致,但生命週期和作用域不同,適合存儲臨時數據。

1. SessionStorage 的核心特點

  • 存儲容量:約 5MB,與 LocalStorage 相同。
  • 生命週期會話級存儲,僅在當前瀏覽器標籤頁有效(關閉標籤頁 / 瀏覽器後數據清空)。
  • 作用域
  • 遵循同源策略,但同一域名的不同標籤頁數據不共享(LocalStorage 共享)。
  • 標籤頁內的 iframe 可共享 SessionStorage(同源情況下)。
  • 操作 API:與 LocalStorage 完全一致(setItemgetItem 等)。

2. SessionStorage 的基本操作

示例:存儲臨時表單數據(頁面刷新不丟失,關閉標籤頁丟失)

javascript

運行

// 設置臨時數據
sessionStorage.setItem("formData", JSON.stringify({ username: "張三", email: "zhangsan@xxx.com" }));

// 讀取數據
const formData = JSON.parse(sessionStorage.getItem("formData"));
console.log(formData.username); // 輸出:張三

// 修改數據
sessionStorage.setItem("formData", JSON.stringify({ username: "李四", email: "lisi@xxx.com" }));

// 刪除數據
sessionStorage.removeItem("formData");
// 或清空所有
sessionStorage.clear();

四、三大存儲方案對比(面試重點)

特性

Cookie

LocalStorage

SessionStorage

存儲容量

4KB

約 5MB

約 5MB

生命週期

可設置過期時間(默認會話級)

永久存儲(手動刪除)

會話級(關閉標籤頁清空)

與服務器交互

隨 HTTP 請求自動發送

不發送

不發送

操作方

前後端均可操作

僅前端操作

僅前端操作

作用域(同源下)

所有標籤頁共享

所有標籤頁共享

僅當前標籤頁有效

安全性

較低(明文,可劫持)

較高(不隨請求發送)

較高

適用場景

登錄狀態、會話跟蹤

永久偏好(如主題、記住密碼)

臨時數據(如表單草稿、臨時令牌)

五、localForage:增強型本地存儲庫

localForage 是第三方庫,基於 IndexedDB 實現,解決了 LocalStorage 容量小、僅支持字符串的問題,同時兼容 LocalStorage/Cookie 作為降級方案。

1. localForage 的核心優勢

  • 存儲容量大:依賴 IndexedDB,容量可達幾十 MB 甚至 GB(瀏覽器限制)。
  • 支持多種數據類型:直接存儲對象、數組、Blob(二進制數據,如圖片),無需 JSON 轉換。
  • 異步操作:避免阻塞主線程(LocalStorage 是同步操作,大量數據可能卡頓)。
  • 自動降級:不支持 IndexedDB 的瀏覽器自動降級為 LocalStorage/Cookie。

2. 基本用法(示例)

javascript

運行

// 1. 引入(CDN 或 npm 安裝)
<script src="https://cdn.jsdelivr.net/npm/localforage@1.10.0/dist/localforage.min.js"></script>

// 2. 存儲數據(異步,支持 await)
async function saveData() {
  // 存儲對象
  await localForage.setItem("user", { name: "張三", age: 20 });
  // 存儲二進制數據(如圖片 Blob)
  const imgBlob = await fetch("img.jpg").then(res => res.blob());
  await localForage.setItem("img", imgBlob);
}

// 3. 讀取數據
async function getData() {
  const user = await localForage.getItem("user");
  console.log(user.name); // 輸出:張三
  const imgBlob = await localForage.getItem("img");
  // 顯示圖片
  const imgUrl = URL.createObjectURL(imgBlob);
  document.querySelector("img").src = imgUrl;
}

// 4. 刪除數據
await localForage.removeItem("user");
// 清空所有
await localForage.clear();

六、總結:存儲方案選擇建議

  1. 需要與服務器交互(如登錄狀態)→ 用 Cookie(或配合 Session)。
  2. 前端永久存儲(如用户偏好、歷史記錄)→ 用 LocalStorage
  3. 前端臨時存儲(如表單草稿、頁面間臨時數據)→ 用 SessionStorage
  4. 存儲大量數據 / 二進制數據(如離線緩存、大文件)→ 用 localForage