浏览器存储与序列化
浏览器存储与序列化 · 阅读后完成下方实验与检查题,再用「标记完成」记录进度。
学习目标
这一课给应用加上「记忆」:用 localStorage(浏览器提供的本地键值存储)保存主题和表单草稿,用 JSON 序列化(把对象变成字符串存起来、再还原的过程)存取结构化数据。读完你应该能安全处理坏数据、版本升级和写入失败这三类存储事故,并且知道为什么它不能当可靠备份。
问题场景
你的课程页有夜间模式,用户切到深色,刷新一下又变回白色;评论区打了两百字,误触刷新全没了。加存储时更糟:用户手动改过 localStorage 里的值,或者旧版本代码存过旧格式,JSON.parse 直接抛异常,初始化代码崩掉,整页白屏。存储代码的功夫,全在「不信任读回来的数据」。
核心解释
localStorage 只能存字符串,对象要经过 JSON 序列化往返:
// 存:对象 → 字符串
localStorage.setItem('theme', JSON.stringify({ mode: 'dark', fontSize: 16 }));
// 读:字符串 → 对象(可能抛错!)
const raw = localStorage.getItem('theme');
const theme = raw ? JSON.parse(raw) : { mode: 'light', fontSize: 14 };
三个必须防的场景,各有标准动作:
- 坏数据:JSON.parse 遇到非法字符串会抛异常。读写都包 try/catch,解析失败就当没有,回退默认值。
- 版本升级:数据结构变了(比如旧版没有 fontSize)。存的时候带版本号,读的时候版本不符就迁移或丢弃:
const KEY = 'theme';
const VERSION = 2;
function loadTheme() {
try {
const raw = localStorage.getItem(KEY);
if (!raw) return null;
const data = JSON.parse(raw);
if (data.version !== VERSION) return migrate(data); // 旧版本先迁移
if (typeof data.mode !== 'string') return null; // 形状不对就丢弃
return data;
} catch {
return null; // 坏数据当没有
}
}
- 写入失败:隐私模式、配额(一般 5MB 左右)占满时,setItem 会抛异常。保存失败要提示用户,不能假装成功。
示例拆解
一个「保存草稿」的最小封装,把防线都装进去:
function saveDraft(text) {
try {
localStorage.setItem('draft', JSON.stringify({ version: 1, text, at: Date.now() }));
return true;
} catch {
return false; // 配额满或隐私模式:由调用方决定怎么提示
}
}
window.addEventListener('beforeunload', () => saveDraft(input.value));
- 恢复草稿用同一套读法:读 → parse(包 try/catch)→ 校验字段 → 使用。
- 「缓存」和「备份」的区别要刻在脑子里:localStorage 可能被用户清掉(清除站点数据)、被隐私模式禁用、换浏览器就没有。它适合偏好、草稿这类「丢了不心疼」的数据;用户认真写的内容该发往服务器入库,别只存本地。
- 验证读失败:开发者工具的 Application(存储)面板,手动把某个值改成乱码再刷新,页面应该照常打开。
动手任务
打开本课实验区:
- 给实验区的 theme 数据加
fontSize字段、把 VERSION 升到 2,运行后观察 v1 旧数据被迁移的日志。 - 点「模拟坏数据」按钮把存储写成非法 JSON,再点「读取」,确认输出是回退值而不是异常。
- 给
saveDraft写调用方:保存失败时在页面显示「当前环境无法保存」的提示。
常见错误
- 裸写 JSON.parse 不包 try/catch:一个坏值让初始化代码崩掉、整页白屏;存储是外部输入,按不信任处理。
- 存对象忘了 stringify:
setItem('k', { a: 1 })会被隐式转成 "[object Object]",读回来永远解析不了。 - 结构升级不迁移:新版读到旧数据直接丢弃,用户偏好全部重置;带版本号是底线。
- 把 localStorage 当数据库或备份:容量小、可被清空、不跨设备同步;只放「丢了可恢复」的数据。
检查与复盘
完成下方检查题确认理解。自查清单:
- 读写 localStorage 有固定套路:try/catch + 版本号 + 字段校验
- 能演示「存进去一个坏值,页面依然正常」
- 能说清哪些数据适合放本地、哪些必须上服务器
参考资料
- MDN:使用 Web Storage API —— localStorage 的能力与边界
- MDN:JSON.stringify —— 序列化行为与坑
- MDN:JSON.parse —— 解析错误与处理
读完这一课了?
标记完成后,工作台会安排接下来的学习。