DEV Community

Cover image for 使用 Local Storage 實現 Client 端數據存儲 - 前端工程師必學的 Web Storage 技術(第二篇)
Let's Write
Let's Write

Posted on • Edited on • Originally published at letswrite.tw

1

使用 Local Storage 實現 Client 端數據存儲 - 前端工程師必學的 Web Storage 技術(第二篇)

本篇要解決的問題

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

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

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


限制

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

瀏覽器上檢查

這邊用 Chrome 當範例。

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

Chrome 上看儲存空間


原生寫法

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

sessionStorage

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

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

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

// 全部清空
sessionStorage.clear();
Enter fullscreen mode Exit fullscreen mode

localStorage

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

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

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

// 全部清空
localStorage.clear();
Enter fullscreen mode Exit fullscreen mode

設定有效期限

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

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

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

// 存值進 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)
Enter fullscreen mode Exit fullscreen mode

推薦套件

sessionStorage、localStorage 這部份有推薦套件:proxy-web-storage

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

如果懶得自己寫一個 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
Enter fullscreen mode Exit fullscreen mode

Demo 及原始碼

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

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

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


瀏覽器上的儲存空間系列

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (0)

Cloudinary image

Optimize, customize, deliver, manage and analyze your images.

Remove background in all your web images at the same time, use outpainting to expand images with matching content, remove objects via open-set object detection and fill, recolor, crop, resize... Discover these and hundreds more ways to manage your web images and videos on a scale.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay