
localStorage 与 sessionStorage 怎么存 JSON 数据存储 API 完整用法【免费下载链接】33-js-concepts 33 JavaScript concepts every developer should know.项目地址: https://gitcode.com/GitHub_Trending/33/33-js-concepts在浏览器应用里保存用户偏好、表单草稿或最近浏览记录时常用的就是 Web StoragelocalStorage和sessionStorage。但这两个 API 只能存字符串——直接把对象传给setItem()会得到[object Object]数据就丢了。33-js-concepts 项目的 localStorage sessionStorage 文档给出了完整做法写入前用JSON.stringify()序列化读取时用JSON.parse()还原并用 try-catch 兜底。本文按“选对存储 → 掌握 API → 正确存取 JSON → 验证”的顺序把文档中的用法串成一条可执行路径。前置条件浏览器Web Storage 属于 HTML5 规范中的 Baseline 特性按文档说明自 2015 年起在所有主流浏览器可用无需额外安装任何东西在支持localStorage/sessionStorage的页面环境浏览器页面、或 jsdom 这类 DOM 测试环境中即可使用。如果要复跑项目自带的测试仓库使用 vitestdevDependencies 中为vitest ^4.0.16jsdom ^27.4.0先执行npm install安装依赖。知识准备文档标注此主题假设你熟悉 DOM 和基础 JavaScript 对象JSON 序列化细节可参考 JSON Deep Dive。先选对存储localStorage 还是 sessionStorage两者 API 完全相同区别在生命周期和作用域来自文档的对比表特性localStoragesessionStorage持久性直到显式清除标签页/窗口关闭时清除作用域同源所有标签页/窗口共享隔离在单个标签页浏览器重启后保留是否页面刷新后保留是是容量限制每 origin 约 5–10 MB每 origin 约 5–10 MB可访问方同源任意标签页仅创建它的标签页这里的 origin 指协议 域名 端口。文档给出的选型示例用 localStorage用户偏好主题、语言、字号、最近浏览项、feature flag / A/B 分组。用 sessionStorage不应跨会话保留的表单数据如formDraft、临时导航状态滚动位置、上次搜索词、一次性提示标记。Web Storage API 全集localStorage和sessionStorage都实现Storage接口方法一致共 6 个成员作用文档给出的示例输出文档示例setItem(key, value)存键值对key 已存在则覆盖setItem(username, alice)后再setItem(username, bob)getItem(username)为bobgetItem(key)取值key 不存在返回nullgetItem(nonexistent)为nullremoveItem(key)删除单个键值对删除后getItem(username)为nullclear()删除该存储中全部键值对谨慎使用clear()后length为0key(index)返回指定下标的 key用于遍历顺序不保证key(99)越界返回nulllength已存条目数存入 2 项后localStorage.length为2文档中的完整演示节选关键调用注释为文档给出的预期结果// 先清空上一轮数据 localStorage.clear() // 存 3 项 localStorage.setItem(name, Alice) localStorage.setItem(role, Developer) localStorage.setItem(level, Senior) console.log(Items stored:, localStorage.length) // 文档示例3 // 覆盖更新 localStorage.setItem(level, Lead) console.log(Updated level:, localStorage.getItem(level)) // 文档示例Lead // 用 key(index) length 遍历全部条目 for (let i 0; i localStorage.length; i) { const key localStorage.key(i) const value localStorage.getItem(key) console.log(${key}: ${value}) } // 删单项后 length 为 2clear() 后为 0 localStorage.removeItem(role) console.log(After removal:, localStorage.length) // 文档示例2 localStorage.clear() console.log(After clear:, localStorage.length) // 文档示例0getItem返回null时文档给出的常用默认值写法是||兜底const theme localStorage.getItem(theme) || light核心JSON 数据的存取方式为什么不能直接存Web Storage 只接受字符串。文档列出的直接存非字符串类型的实际结果文档示例localStorage.setItem(count, 42) typeof localStorage.getItem(count) // string值是 42 localStorage.setItem(isActive, true) localStorage.getItem(isActive) // true字符串不是布尔 // 对象变 [object Object]——数据丢失 localStorage.setItem(user, { name: Alice }) localStorage.getItem(user) // [object Object] // 数组变成逗号分隔字符串 localStorage.setItem(items, [1, 2, 3]) localStorage.getItem(items) // 1,2,3字符串不是数组正确做法JSON.stringify / JSON.parse存时用JSON.stringify()取时用JSON.parse()// 存对象 const user { name: Alice, age: 30, roles: [admin, user] } localStorage.setItem(user, JSON.stringify(user)) // 取对象 const storedUser JSON.parse(localStorage.getItem(user)) console.log(storedUser.name) // 文档示例Alice console.log(storedUser.roles) // 文档示例[admin, user] // 存数组 const favorites [item1, item2, item3] localStorage.setItem(favorites, JSON.stringify(favorites)) const storedFavorites JSON.parse(localStorage.getItem(favorites)) console.log(storedFavorites[0]) // 文档示例item1读取时的 null 处理getItem对不存在的 key 返回null直接JSON.parse(null)得到null再访问属性会抛TypeError。文档给出的安全写法是给JSON.parse一个字符串默认值// 危险写法settings 为 null 时 settings.theme 抛 TypeError // const settings JSON.parse(localStorage.getItem(settings)) // 安全写法提供默认值 const settings JSON.parse(localStorage.getItem(settings)) || {} const theme settings.theme || light // 数组同理默认给 [] const recent JSON.parse(localStorage.getItem(recentlyViewed) || [])JSON 序列化的四个坑文档明确列出的限制文档示例// 1. Date 变字符串需手动还原 const data { created: new Date() } localStorage.setItem(data, JSON.stringify(data)) const parsed JSON.parse(localStorage.getItem(data)) console.log(typeof parsed.created) // string不是 Date parsed.created new Date(parsed.created) // 文档给出的还原方式 // 2. undefined 值直接丢失 JSON.stringify({ a: 1, b: undefined }) // {a:1}——b 没了 // 3. 函数不可序列化 JSON.stringify({ greet: () hello }) // {} // 4. 循环引用直接抛错 const circular { name: test } circular.self circular JSON.stringify(circular) // TypeError: Converting circular structure to JSON因此不要用 Web Storage 存包含函数或自引用的结构Date 字段在读取侧统一用new Date(...)重建。封装一个安全的存储工具文档给出一个自动处理 JSON 和异常的工具对象可作为业务代码里的主力路径const storage { set(key, value) { try { localStorage.setItem(key, JSON.stringify(value)) return true } catch (error) { console.error(Storage set failed:, error) return false } }, get(key, defaultValue null) { try { const item localStorage.getItem(key) return item ? JSON.parse(item) : defaultValue } catch (error) { console.error(Storage get failed:, error) return defaultValue } }, remove(key) { localStorage.removeItem(key) }, clear() { localStorage.clear() } } // 使用文档示例 storage.set(user, { name: Alice, premium: true }) const user storage.get(user) // 文档示例{ name: Alice, premium: true } const missing storage.get(nonexistent, { guest: true }) // 文档示例{ guest: true }get的第二个参数是默认值key 不存在或存的不是合法 JSON 时返回它而不是抛错。验证跑项目自带的测试用例仓库中有一整套针对上述用法的测试文件 tests/beyond/browser-storage/localstorage-sessionstorage/localstorage-sessionstorage.test.js文件头部用vitest-environment jsdom声明运行在 jsdom 环境vitest.config.js默认环境是 node该文件自身覆盖了从而提供localStorage/sessionStorage。在仓库根目录执行npm install npx vitest run tests/beyond/browser-storage/localstorage-sessionstorage/localstorage-sessionstorage.test.js说明npx vitest run 文件路径是 vitest 按文件过滤的用法只跑这一个测试文件package.json里的npm test脚本对应vitest run会执行tests/下全部测试包含其他主题验证本主题时建议用上面的过滤命令。该测试文件覆盖的断言包括直接存对象得到[object Object]、存数组得到1,2,3JSON.stringify/parse后对象、数组、嵌套对象可原样取回Date 被转成字符串、undefined/函数被丢弃、循环引用抛TypeError封装工具的默认值回退key 不存在或非法 JSON 时返回defaultValuekey()、length、遍历模式以及storageAvailable特性检测函数。成功条件vitest 输出中该文件的测试全部通过、无失败项。不想跑测试时也可以直接在浏览器 DevTools 控制台执行本文代码块验证存对象后console.log取回的值应能访问.name等属性localStorage.length应随存取增减。可选用法storage 事件做跨标签页同步当同一 origin 的另一个标签页修改了存储当前页面会收到storage事件。文档特别强调事件不会在发起修改的标签页触发只在其他标签页触发。window.addEventListener(storage, (event) { console.log(Key:, event.key) // 被修改的 keyclear() 时为 null console.log(Old value:, event.oldValue) // 旧值新 key 时为 null console.log(New value:, event.newValue) // 新值删除 key 时为 null console.log(URL:, event.url) // 发起修改的文档 URL console.log(Storage area:, event.storageArea) // 被修改的 Storage 对象 })文档给出的手动验证步骤两个标签页打开同一站点两边都打开 DevTools 控制台在 Tab 1 添加监听器window.addEventListener(storage, (e) console.log(Changed:, e.key))在 Tab 2 执行localStorage.setItem(test, value)Tab 1 控制台输出Changed: test文档示例。文档还给了一个实例监听authToken被其他标签页删除event.newValue null时跳转/login实现跨标签页登出同步。配额、隐私模式与特性检测容量与 QuotaExceededError文档给出的各浏览器限额均为每 origin 约 5 MBChrome / Firefox / Safari / Edge且 quota 按 origin 计算——https://example.com下所有页面共享同一额度。超限后setItem()抛QuotaExceededError文档给出的处理写法function safeSetItem(key, value) { try { localStorage.setItem(key, value) return true } catch (error) { if (error.name QuotaExceededError) { console.error(Storage quota exceeded!) // 文档建议清理旧数据、提示用户等 return false } throw error // 非配额错误重新抛出 } }数据超过 5 MB 或需要索引查询时文档的选型表建议改用 IndexedDB参见 IndexedDB不要把大数据塞进 Web Storage。隐私浏览模式文档列出的差异Safari 隐私模式下任何写入都会抛QuotaExceededErrorChrome、Firefox、Edge 隐私模式下 localStorage 可用但窗口关闭时清空所有浏览器的 sessionStorage 在隐私模式下均可用、关闭时清空。特性检测所以文档要求先检测可用性再使用function storageAvailable(type) { try { const storage window[type] const testKey __storage_test__ storage.setItem(testKey, testKey) storage.removeItem(testKey) return true } catch (error) { return ( error instanceof DOMException error.name QuotaExceededError // 已有存量数据时QuotaExceededError 仍可视为可用 storage storage.length ! 0 ) } } if (storageAvailable(localStorage)) { localStorage.setItem(key, value) } else { console.warn(localStorage not available) // 文档建议回退到 cookies、内存存储或提示用户 }安全边界文档明确警告Web Storage 不做访问隔离页面上运行的任何 JS包括 XSS 注入的脚本都能读取全部条目因此密码、支付信息、身份证号、认证 token、API key一律不存Web Storage认证 token 改用 HTTP-only cookies只存非敏感数据偏好、UI 状态、公开的缓存数据同时建议启用 CSP、消毒所有用户输入。限制回顾Web Storage 是同步API大数据量操作会阻塞主线程文档原话提醒只能存字符串对象/数组必须经JSON.stringifyDate、undefined、函数、循环引用无法经 JSON 保真往返每 origin 约 5 MB各浏览器均约 5 MB超限额要捕获QuotaExceededErrorlocalStorage跨标签页共享、sessionStorage按标签页隔离storage事件只通知其他标签页当前标签页内不会有回显同一标签页内的联动逻辑需要自行实现。【免费下载链接】33-js-concepts 33 JavaScript concepts every developer should know.项目地址: https://gitcode.com/GitHub_Trending/33/33-js-concepts创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考