使用 Local Storage 實現 Client 端數據存儲 - 前端工程師必學的 Web Storage 技術（第二篇）
Tags: javascript, beginners, tutorial, webdev
Published: 2022-11-15 13:00:48

## 本篇要解決的問題

上一篇寫的是最常用到的 [Cookie](https://www.letswrite.tw/client-storage-cookie/)，裡面也有寫到 Cookie 通常是存有目的性的資料。如果只是想存一些不重要的資料，像是內容網站上很常會有的 放大 / 縮小 文字的按鈕，或是切換深色模式的操作，總不能使用者今天點了一次文字放大後，下次再進來頁面還得再點一次，這時就可以選擇存在瀏覽器上。

而像這種不是很重要的記錄存取，就可以選擇 localStroage。

sessionStorage 跟 localStorage 最大的差別在於，sessionStorage 是當使用者關掉了頁籤，紀錄就會消失；而 localStorage 是除非我們去刪除它，或是使用者刪除它，不然就不會過期，永遠存在。

---

## 限制

- 限制大小：約 5 MB
- 限制期限：sessionStorage 關閉頁籤即刪除，localStorage 要主動刪除或程式刪除
- 資料格式：僅接受字串

---

## 瀏覽器上檢查

這邊用 Chrome 當範例。

如果想看網站上存了什麼 sessionStorage、localStorage，在網頁上點右鍵按檢查，在面板上點擊「應用程式」，就會看到「本機儲存空間（localStorage）」、「工作階段儲存空間（sessionStorage）：

![Chrome 上看儲存空間](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mlk3ug517fxclvmvkkuz.png)

---

## 原生寫法

新增、取得、刪除 sessionStorage、localStorage 的原生寫法很簡單，整理如下。

### sessionStorage

```javascript
// 存
sessionStorage.setItem('key', 'value');

// 取
const ssData = sessionStorage.getItem('key');

// 刪
sessionStorage.removeItem('key');

// 全部清空
sessionStorage.clear();
```

### localStorage

```javascript
// 存
localStorage.setItem('key', 'value');

// 取
const lsData = localStorage.getItem('key');

// 刪
localStorage.removeItem('key');

// 全部清空
localStorage.clear();
```

---

## 設定有效期限

雖說 localStorage 是沒有期限的，但可以換一種方式讓它跟 Cookies 一樣有期限。

方式就是，我們在存一個 localStorage 時，一併存一個我們希望它過期的日期上去。

之後當我們要取用時，先拿存的日期來比對當下時間，如果存的時間較大就代表過期，就當作沒取到這個 localStorage 的資料，並把它刪除。

```javascript
// 存值進 localStorage
function setStorageExpire({ key, value, expire }) {
  localStorage.setItem(key, JSON.stringify({
    value, expire
  }));
}

// 從 localStorage 取值
function getStorageExpire({ key }) {
  const result = JSON.parse(localStorage.getItem(key));
  const current = new Date().getTime();

  // 現在時間小於過期時間，代表還沒過期
  if(current < result.expire) {
    return result.value
  }
  // 大於就是過期
  else {
    localStorage.removeItem(key);
    return false;
  }

}

// 存一筆資料
setStorageExpire({
  key: 'demo-key',
  value: 'demo-value',
  expire: new Date('2022/11/16').getTime()
});

// 取值
const demoResult = getStorageExpire({ key: 'demo-key' });
console.log("🚀", demoResult)
```

---

## 推薦套件

sessionStorage、localStorage 這部份有推薦套件：[proxy-web-storage](https://github.com/KID-joker/proxy-web-storage)。

這套在 GitHub 上的星星數還沒到很多，但試用了一下覺得蠻方便的，除了可以在存的時候就存進不同的資料型別，也可以寫一個有效時間進去判斷資料是否過期。

如果懶得自己寫一個 JavaScript 來用，可以考慮直接引用。

```javascript
// 先安裝 proxy-web-storage
$ npm install proxy-web-storage 或 $ yarn add proxy-web-storage

// 開始使用
import { local, session } from 'proxy-web-storage';

// number
local.demo_number = 0;

// boolean
local.demo_boolean = false;

// undefined
local.demo_undefined = undefined;

// null
local.demo_null = null;

// object
local.demo_object = { hello: 'world' };

// array
local.demo_array = ['hello'];

// Date
local.demo_Date = new Date('2000-01-01T00:00:00.000Z');

// RegExp
local.demo_RegExp = /d(b+)d/g;

// function
local.demo_function = function() {
  return 'Hello proxy-web-storage!';
};

// 過期範例
local.test = 'hello proxy-web-storage';
local.setExpires('test', Date.now() + 10000);

// 10 秒內
local.test // 'hello proxy-web-storage'

// 10 秒後到期
local.test // undefined
```

---

## Demo 及原始碼

本篇一樣有製作 Demo，原始碼也放在 GitHub 上，取用之前麻煩分享本篇或點個星星，你的小小動作對本站都是大大的鼓勵。

Demo：<https://letswritetw.github.io/letswrite-client-storage/>

GitHub：<https://github.com/letswritetw/letswrite-client-storage>

---

## 瀏覽器上的儲存空間系列

- [Cookies](https://www.letswrite.tw/client-storage-cookie/)
- [sessionStorage、localStorage](https://www.letswrite.tw/client-storage-local/)
- [IndexedDB](https://www.letswrite.tw/client-storage-idb/)