資料儲存
持久資料一律用 sdk.storage
ts
import { sdk } from '@im/miniapp-sdk';
await sdk.storage.set('draft', { title: '週末聚餐', people: 4 });
const draft = await sdk.storage.get<{ title: string; people: number }>('draft'); // 沒有時為 null
await sdk.storage.remove('draft');
await sdk.storage.clear(); // 清掉這個小程序的全部資料- 隔離:每個「伺服器 × 帳號 × 小程序」一份,其他小程序、其他帳號都讀不到。
- 容量:每份 10 MB,以所有 key 與 value 的 UTF-8 位元組合計。超過時
set以QUOTA_EXCEEDED失敗,原本的資料不變。 - 格式:值以 JSON 存放,
set時JSON.stringify、get時JSON.parse。只能存可以 JSON 序列化的值;要刪除請用remove(set(key, undefined)會以INVALID_PARAMS失敗)。 - key:1–128 字。單一 value:序列化後最多 1 MB(以字串長度計;整則呼叫訊息上限也是 1 MB,實際可用略少)。
- 寫入時機:寫入先進記憶體,約 0.3 秒後存檔;App 退到背景、關閉小程序時也會立即把已寫入的資料存檔。App 被系統強制結束時,最後 0.3 秒內的寫入可能遺失。
- 保活期間也能用:在
app.pause(或邏輯層的onHide)裡寫入沒問題,但這時「退到背景的立即存檔」已經做完,這筆約 0.5 秒內才會存檔。重要的資料請在變更當下就寫入,不要全部留到app.pause。 - 註銷帳號時刪除:使用者註銷帳號時,他在所有小程序的資料一起刪除。
- 邏輯層與畫面層讀寫的是同一份資料。
不要存 token
sdk.auth.getSession() 本身有快取,每次需要時直接呼叫即可;把 token 存進 storage 只會拿到過期的 token。
瀏覽器的儲存
小程序的網址是 127.0.0.1:<隨機埠>,埠會被系統回收再分配給其他小程序或其他帳號。瀏覽器的持久儲存會被之後拿到同一個埠的人讀到,所以容器限制如下:
| API | 行為 |
|---|---|
localStorage | 改由 sessionStorage 提供:只在這次開啟有效(重新整理、保活接回都還在;關閉並釋放後消失) |
sessionStorage | 正常,只在這次開啟有效 |
document.cookie | 讀到空字串,寫入無效 |
indexedDB、caches、navigator.serviceWorker | 不存在(undefined) |
navigator.storage.getDirectory()(OPFS) | 一律 reject |
Worker 與 iframe 裡不得使用持久儲存
上面的限制只作用在頁面本身。Web Worker 與同源 iframe 有自己的全域物件,容器擋不到:在 Worker 裡使用 IndexedDB、Cache Storage、OPFS 屬於違規,資料會被其他小程序讀到。
該存在哪裡
| 資料 | 放哪裡 |
|---|---|
| 使用者設定、草稿、上次的篩選條件 | sdk.storage |
| 只在這次使用有效的狀態(表單暫存、捲動位置) | 記憶體或 sessionStorage/localStorage |
| 跨裝置要同步的資料 | 你的後端 |
| 敏感資料(付款資訊、證件) | 不要存在手機上 |