安全存取JSON数据需校验、兜底和类型转换:存前检查非法值并处理Date/RegExp,用try-catch包裹序列化;取时判空再解析,设默认值;敏感数据禁用localStorage,改用httpOnly Cookie或IndexedDB。

在前端缓存中安全存取 JSON 数据,核心是用 localStorage 或 sessionStorage 配合 JSON 序列化与反序列化,但必须处理类型丢失、解析异常和数据校验三类风险。直接 JSON.stringify() 和 JSON.parse() 不够安全,关键在兜底逻辑和边界判断。
存数据:先校验再序列化,避开非法值
localStorage 只接受字符串,但原始对象可能含函数、undefined、Date、RegExp 或循环引用——这些都会导致 JSON.stringify() 失败或静默丢数据。
- 对值做基础类型检查,拒绝函数、
undefined、Symbol - 把
Date转成时间戳(date.getTime()),RegExp存为{ source, flags }对象 - 用
try...catch包裹序列化过程,失败时记录错误而非静默忽略 - 推荐封装写法:
function saveToStorage(key, data) {
try {
// 简单校验:排除 null/undefined,其他类型尽量转成可序列化结构
if (data == null) throw new Error('数据为空');
const jsonStr = JSON.stringify(data);
localStorage.setItem(key, jsonStr);
} catch (e) {
console.error(`存储 ${key} 失败:`, e.message);
}
}
取数据:先判空再解析,始终设默认值
localStorage.getItem() 返回 null(未设置)或字符串,但 JSON.parse(null) 得 null,JSON.parse('') 直接报错。不能假设读出来的一定是合法 JSON 字符串。
- 先检查返回值是否为非空字符串,否则直接返回默认值
- 用
try...catch包裹JSON.parse(),防止损坏数据导致脚本中断 - 默认值建议按使用场景设定,如数组用
[],对象用{} - 示例:
function loadFromStorage(key, defaultValue = []) {
const str = localStorage.getItem(key);
if (!str || typeof str !== 'string') return defaultValue;
try {
return JSON.parse(str);
} catch (e) {
console.warn(`解析 ${key} 失败:`, e.message);
return defaultValue;
}
}
特殊类型要手动转换,别依赖原生 JSON
原生 JSON.stringify() 会把 Date 转成 ISO 字符串,但 JSON.parse() 不会还原为 Date 实例;Map、Set、RegExp 等根本无法序列化。
- 存
Date:用date.getTime(),取时new Date(ms) - 存正则:转成
{ source: 'pattern', flags: 'g' },取时new RegExp(obj.source, obj.flags) - 含函数、原型方法或自定义类的数据,不适合用
localStorage,应改用IndexedDB
敏感数据别放 localStorage,优先考虑更安全的方案
localStorage 是全局可读的,任何运行在同源页面上的脚本都能访问,不适用于 token、密码、用户身份等敏感信息。
- 认证类数据建议用
httpOnly Cookie或内存变量(如模块内常量) - 大量或结构复杂的数据(如带方法的对象、嵌套 Map/Set)更适合
IndexedDB - 临时会话数据可用
sessionStorage,关闭标签页即清除,比localStorage更可控
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











