Files
2026-07-13 21:36:17 +08:00

72 lines
1.9 KiB
Markdown

---
title: Version and Minimize localStorage Data
impact: MEDIUM
impactDescription: 防止模式冲突,减小存储体积
tags: client, localStorage, storage, versioning, data-minimization
---
## Version and Minimize localStorage Data
为键名添加版本前缀,只存储必要的字段。可防止模式冲突,避免意外存储敏感数据。
**不正确的写法:**
```typescript
// 无版本号、存储全部字段、无错误处理
localStorage.setItem('userConfig', JSON.stringify(fullUserObject))
const data = localStorage.getItem('userConfig')
```
**正确的写法:**
```typescript
const VERSION = 'v2'
function saveConfig(config: { theme: string; language: string }) {
try {
localStorage.setItem(`userConfig:${VERSION}`, JSON.stringify(config))
} catch {
// 在无痕/隐私浏览模式下、配额超限或禁用存储时会抛出异常
}
}
function loadConfig() {
try {
const data = localStorage.getItem(`userConfig:${VERSION}`)
return data ? JSON.parse(data) : null
} catch {
return null
}
}
// 从 v1 迁移到 v2
function migrate() {
try {
const v1 = localStorage.getItem('userConfig:v1')
if (v1) {
const old = JSON.parse(v1)
saveConfig({ theme: old.darkMode ? 'dark' : 'light', language: old.lang })
localStorage.removeItem('userConfig:v1')
}
} catch {}
}
```
**只存储服务端响应中的最小字段:**
```typescript
// User 对象有 20+ 个字段,只存储 UI 需要的内容
function cachePrefs(user: FullUser) {
try {
localStorage.setItem('prefs:v1', JSON.stringify({
theme: user.preferences.theme,
notifications: user.preferences.notifications
}))
} catch {}
}
```
**始终用 try-catch 包裹:** `getItem()``setItem()` 在无痕/隐私浏览模式下(Safari、Firefox)、配额超限或存储被禁用时会抛出异常。
**优势:** 通过版本号实现模式演进、减小存储体积、避免存储令牌/PII/内部标志位。