HTML5 词条目录
前端Wiki/HTML5/深入/Web Storage

存储实战与封装

直接裸用 localStorage 有三个常见坑,封装一层即可解决:对象忘转 JSON——统一在 set/get 里做序列化,业务代码永远存取原对象;容量超限抛异常(QuotaExceededError)——写入包 try/catch,失败时提示用户或降级;键名冲突——所有键加统一前缀,多模块共存互不干扰。

进阶技巧:监听 storage 事件实现跨标签页同步——A 标签页改了数据,B 标签页立即收到事件(注意:本标签页自己的修改不触发),可用于"多标签页登录状态同步""购物车实时刷新"。

最后是安全边界:localStorage 对同源下所有 JS 可读,XSS 攻击能偷走里面的内容,所以不要存敏感凭证(密码、长期有效的 token)。存过期时间做"本地缓存失效"也是实战常用手法。

本节要点封装三件事:JSON 自动转换、try/catch 防超限、前缀防冲突;storage 事件做跨标签页同步;敏感信息不要放 localStorage,可加过期时间做缓存。
JavaScript
// 一个带 JSON 序列化、前缀隔离、异常保护的存储工具
var store = {
  set: function (key, value) {
    try {
      localStorage.setItem('app:' + key, JSON.stringify(value));
    } catch (e) {
      console.warn('存储失败(容量已满或被禁用)', e);
    }
  },
  get: function (key, def) {
    var raw = localStorage.getItem('app:' + key);
    if (raw === null) return def;          // 不存在时给默认值
    try { return JSON.parse(raw); }
    catch (e) { return raw; }              // 兼容非 JSON 的旧数据
  },
  remove: function (key) {
    localStorage.removeItem('app:' + key);
  }
};

store.set('cart', [{ id: 1, n: 2 }]);      // 直接存对象
store.get('cart', []);                     // 直接取对象

// 跨标签页同步:其他标签页的修改会触发 storage 事件
window.addEventListener('storage', function (e) {
  console.log('另一个标签页改动了:', e.key, '→', e.newValue);
});