@ionic/storage存入的序列化JSON取出后无法正常解析如何解决
问题原因分析
- 双重序列化/反序列化冲突:@ionic/storage v3及以上版本默认开启自动JSON序列化/反序列化能力,如果自己手动对数据做
JSON.stringify后再存入,相当于重复序列化,取数据时要么拿到的是已经被框架反序列化完成的对象(再次JSON.parse会直接报错),要么拿到经过两次转义的异常字符串,表现为乱码无法解析。 - 存储驱动编码不兼容:@ionic/storage支持IndexedDB、SQLite、LocalStorage等多种底层驱动,部分驱动对特殊字符(emoji、非UTF-8字符、特殊转义符)的处理逻辑存在差异,存入时自动做了额外编码,取出时编码不匹配就会出现乱码。
- 异步时序问题:
set方法是异步操作,如果未等await set执行完成就跳转页面、调用get方法,会拿到未写入完成的不完整数据或者旧值,导致解析失败。 - 源数据序列化异常:待存储的
response对象如果存在循环引用、不可序列化的属性(比如函数、Symbol),会导致JSON.stringify执行失败,存入的是错误的空值、异常字符串,取出后自然无法解析。
排查步骤
- 先打印原始值定位问题:存入前打印手动序列化的结果
console.log('存入前序列化内容', JSON.stringify(response)),取出后先不要直接调用JSON.parse,打印原始值和类型console.log('取出原始内容', conversationResource, typeof conversationResource),确认是否存在双重转义、内容不完整、类型异常等问题。 - 校验@ionic/storage配置:检查项目中Storage初始化的参数,确认
jsonParse配置项是否开启,该参数为true时表示框架自动做序列化/反序列化。 - 捕获序列化异常:用try-catch包裹存入逻辑,确认序列化阶段没有报错:
try { const serializedData = JSON.stringify(response); console.log('序列化成功', serializedData); await set('currentConversation', serializedData); } catch (err) { console.error('序列化阶段出错', err); }
- 验证异步时序:在
set执行完成后加日志确认写入完成,再执行后续跳转、取数逻辑,排除未写入完成就提前读取的问题。
解决方案
- 处理序列化冲突:如果确认框架开启了自动序列化,直接去掉自己写的手动序列化/反序列化逻辑即可,直接存对象:
await set('currentConversation', response),取的时候直接拿结果:const conversationResource = await get('currentConversation');如果想要自己控制序列化逻辑,在初始化Storage时配置jsonParse: false关闭自动序列化即可。 - 处理编码兼容问题:如果确认是特殊字符导致的编码异常,存入前先做URI编码:
await set('currentConversation', encodeURIComponent(JSON.stringify(response))),取出后先解码再解析:JSON.parse(decodeURIComponent(conversationResource))。 - 修复异步时序问题:将页面跳转、取数逻辑放到
set执行完成之后,比如把路由跳转逻辑写在await set的下一行,或者set的then回调中。 - 修复源数据问题:如果
response存在循环引用,可以使用支持循环引用的序列化工具,或者手动移除不可序列化的属性后再存入。
内容的提问来源于stack exchange,提问作者IWI
相关产品推荐
相关产品推荐

