Stories

Detail Return Return

Web前端入門第 83 問:JavaScript localStorage 有大小限制嗎?溢出會怎樣? - Stories Detail

本地存儲除了 Cookie 外,還有 localStoragesessionStorage,本文一探 localStorage

localStorage

此 API 存入的數據會 永久 保存在瀏覽器中,除非用户手動刪除。

localStorage 能用於同一瀏覽器同一域名跨標籤頁通信。

同一瀏覽器無痕模式非無痕模式下,localStorage 存儲的數據無法互通,且無痕模式存入的數據在瀏覽器關閉時候會被清除(所有無痕模式窗口關閉也會清除)!!

API

localStorage 對象暴露的 API 很簡單,就幾個增刪改操作方法:

// 只讀屬性,返回本地存儲項的數目
localStorage.length

// 獲取本地存儲的第 n 個鍵名
localStorage.key(n)
// 獲取本地存儲的值
localStorage.getItem(key)
// 寫入本地存儲
localStorage.setItem(key, value)
// 刪除本地存儲
localStorage.removeItem(key)
// 清空所有本地存儲
localStorage.clear()

示例:

(() => {
  // 監聽 storage 事件
  window.addEventListener('storage', e => {
    // 本頁面不會觸發 storage 事件
    // 需要新開一個 tab 查看變化
    console.log(e);
  })

  // 寫入數據
  localStorage.setItem('type', '公眾號');
  localStorage.setItem('name', '前端路引');

  // 獲取本地存儲長度
  console.log(localStorage.length);

  // 循環打印本地存儲
  for (let i = 0; i < localStorage.length; i++) {
    const key = localStorage.key(i);
    const value = localStorage.getItem(key);
    console.log(`${key}: ${value}`);
  }
  // 移除單個本地存儲
  localStorage.removeItem('name');
  // 移除所有本地存儲
  localStorage.clear();
})()

以上代碼中的 storage 事件只會在有多個標籤頁打開的情況下,才會觸發;只有一個窗口時, localStorage 的改變並不會觸發 storage 事件。

MDN 中有這麼一句話:

83-0

原文:https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API

上面代碼執行結果:

83-1

如果要想在當前頁頁能觸發 storage 事件,可以派發一個模擬事件:

(() => {
  // 移除所有本地存儲
  localStorage.clear();

  // 監聽 storage 事件
  window.addEventListener('storage', e => {
    console.log(e);
  })

  // 自定義寫入函數,封裝事件派發
  function setItem (key, value) {
    // 模擬 storage 事件
    const ev = new StorageEvent('storage', {
      key,
      newValue: value,
      oldValue: localStorage.getItem(key),
      url: location.href,
    });
    window.dispatchEvent(ev);
    localStorage.setItem(key, value);
  }
  setItem('type', '公眾號');
  setItem('name', '前端路引');
})()

執行結果:

83-2

功能檢測

此處分享一個 MDN 文檔中的檢測 localStorage 是否可用的代碼片段:

83-3

來源:https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API

大小與個數限制

分享完 API 的使用方式,再看看各個瀏覽器之間的大小限制。

Chrome

Chrome 瀏覽器本地存儲配額為 5MB 大小,意思就是所有存儲的數據(鍵和值一起的長度)加起來不能超過 5MB。

(() => {
  // 移除所有本地存儲
  localStorage.clear();
  const key = 'name';
  const max = 5 * 1024 * 1024;
  // 測試極限值
  const value = 'a'.repeat(max - key.length);
  // 測試中文
  // const value = '中'.repeat(max - key.length);
  // 測試溢出
  // const value = 'a'.repeat(max - key.length + 1);
  localStorage.setItem(key, value);
})()

以上代碼為剛好能存下的長度,如果超出一個字符,將會報錯:

Uncaught QuotaExceededError: Failed to execute 'setItem' on 'Storage': Setting the value of '****' exceeded the quota.

錯誤截圖:

83-4

Edge

自從 Edge 換成 Chromium 內核之後,它倆的所有行為基本表現一直,以前的 IE 內核沒做測試,有興趣的同學可以測試看看 IE 內核的表現行為。

Firefox

Firefox 也是限制 5MB 大小,但在溢出時的報錯不一樣:

Uncaught DOMException: The quota has been exceeded.

錯誤截圖:

83-5


根據以上測試結果得出:Firefox(138.0.4)、Edge(136.0.3240.92)、Chrome(136.0.7103.114)三大瀏覽器都是共用 5MB 存儲空間,數量與每個本地儲存項的大小有關,比如每次寫入一個 1MB 的數據,那麼就支持寫入 5 個!!

中英文:與 Cookie 不同,localStorage 中的中文和英文計算方式一致,一箇中文也按照一個字符計算!!

寫在最後

localStorage 僅支持字符串存儲,所以在存儲 JS 的 JSON 數據時,需要將 JSON 數據轉為字符串再存儲。

由於本人是 windows 環境,所以無法測試 Safari 瀏覽器的具體情況,有興趣可以自測一下(有網友測試 safari 13.0.2 限制 2.5MB)。

在移動端的瀏覽器和 Webview 中使用 localStorage 時需注意,由於 APP 會自動優化存儲空間,寫在本地存儲中的數據隨時都可能被清空刪除,所以本地存儲的數據是不可靠的。

user avatar tianmiaogongzuoshi_5ca47d59bef41 Avatar toopoo Avatar jingdongkeji Avatar razyliang Avatar huajianketang Avatar hard_heart_603dd717240e2 Avatar Dream-new Avatar dunizb Avatar jiavan Avatar febobo Avatar yqyx36 Avatar munergs Avatar
Favorites 74 users favorite the story!
Favorites

Add a new Comments

Some HTML is okay.