localstorage存用户偏好需统一对象结构并json序列化读写,监听storage事件同步跨页变更,加入try-catch容错及二次验证,避免直接存原始值或用于敏感数据。

用 localStorage 保存离线配置项是轻量、可靠且兼容性好的方案,适合存主题、语言、默认排序、通知开关等用户偏好类数据。关键不是“能不能存”,而是“怎么存得稳、读得准、用得久”。
配置项结构要清晰,统一用对象封装
别直接存原始值(如 localStorage.setItem('theme', 'dark')),而应把所有配置归入一个对象,再整体序列化:
- 推荐结构示例:{ theme: 'dark', lang: 'zh-CN', notifications: true, pageSize: 20 }
- 这样便于批量读写、版本演进和逻辑隔离
- 避免零散 key 堆积(如 'theme'、'themeMode'、'isDark' 混用),后期维护成本高
读写必须走 JSON 序列化+try-catch
localStorage 只认字符串,不处理类型。跳过 JSON.stringify / JSON.parse,90% 的问题都出在这儿:
- 写入时:始终用 JSON.stringify(config),哪怕 config 是布尔或数字
- 读取时:先 getItem,再 JSON.parse,并检查返回值是否为 null 或解析失败
- 包裹 try-catch,捕获 QuotaExceededError(配额超)、DOMException(无痕模式禁用)等静默错误
注意跨页面同步与初始化时机
配置项常需在多个页面间一致生效,比如切到设置页改了主题,首页也要立刻响应:
- 监听 storage 事件,当其他标签页修改配置时,自动刷新当前页 UI
- 首次加载时,优先从 localStorage 读取;若读不到,再用默认值初始化,并立即写回,避免每次都是“未配置”状态
- 不要在 DOM 尚未就绪时就读取(如 script 放 head 里但没加 defer),容易取到空值
容错与降级策略不能少
localStorage 并非 100% 可靠,尤其在 iOS Safari 低内存、无痕模式、配额满时会静默失效:
- 写入后建议 二次验证:setItem 后立刻 getItem 对比,确认写入成功
- 准备 fallback 方案,例如退回到内存变量(const fallbackConfig = {...}),保证功能不崩
- 对敏感操作(如登录态 token)不用 localStorage,改用更安全的 HttpOnly Cookie + 后端校验











