uni-app JSON结构特定长度写入缓存后读取格式异常

发布于 1周前 作者 bupafengyu 来自 Uni-App

uni-app JSON结构特定长度写入缓存后读取格式异常

项目 信息
产品分类 uniapp/App
PC开发环境操作系统 Mac
PC开发环境操作系统版本号 14.2.1 (23C71)
HBuilderX类型 正式
HBuilderX版本号 3.99
手机系统 Android
手机系统版本号 Android 13
手机厂商 小米
手机机型 12
页面类型 vue
vue版本 vue2
打包方式 云端
项目创建方式 HBuilderX

示例代码:

和附件一起发送

操作步骤:

使用我提供的附件里的JSON,然后setStorageSync之后,马上getStorageSync就可以看到异常结果

预期结果:

正确的写入 JSON 到缓存,正确的读取缓存到 JSON 结构

实际结果:

从缓存中读出的结构异常

bug描述:

用户报了一个特殊问题,总是导致运行卡住。通过反复测试,发现此用户的JSON 格式数据写入缓存后,在读取出来时,数据内容不对,变成了string类型,同时头部多出了“{“type”:“object”,“data”:”,然后后面是JSON的内容“{A:1,B:2…}
导致数据的读取出现问题。
如果我随便修改一个字段,把长度少一位或是多一位,都可以正常处理,正好就在这个长度不行。应该是getStorageSync或是setStorageSync的内部处理有些问题。


8 回复

HBuilderX 4.04.2024031519-alpha 已修复。


我这里使用附件里的json测试是正常的,上传个完整的工程吧

我直接工程打包了。您看一下。我仔细查了一下。发现两个问题。

如果在 3.99 版本,是写入后,读出格式的问题。
如果在 4.0.1 测试版本,更离谱,大量的字段都是 {},{},{}

您可测试一下。

收到,这边排查下

回复 YUANRJ: 您那边重现了这个问题吗?

回复 百世创一: 已重现,后续有进展会更新此帖

只要把这个JSON结构加一个字节,或是删除一个字节,在 3.99 版本都看起来没问题了。但是在 4.01 版本还是有问题,感觉是同步写入setStorageSync还未完成,同步读取getStorageSync的数据就开始读,导致信息不完整。

在使用 uni-app 进行开发时,如果你将特定长度的 JSON 结构写入缓存后,读取时出现格式异常,可能是由于以下几个原因导致的。以下是一些可能的原因和解决方法:


1. JSON 数据序列化问题

在将 JSON 数据写入缓存时,需要使用 JSON.stringify() 将对象转换为字符串。如果数据中包含特殊字符或格式问题,可能导致读取时解析失败。

解决方法: 确保在写入缓存时正确序列化 JSON 数据,并在读取时使用 JSON.parse() 解析。

// 写入缓存
const data = { key: 'value' };
uni.setStorageSync('myData', JSON.stringify(data));

// 读取缓存
const storedData = uni.getStorageSync('myData');
const parsedData = JSON.parse(storedData);
console.log(parsedData);

2. 缓存数据长度限制

uni-app 的缓存(如 uni.setStorageSync)有大小限制,通常为 10MB。如果 JSON 数据过大,可能会导致写入失败或读取异常。

解决方法:

  • 检查数据大小,确保不超过缓存限制。
  • 如果数据过大,可以考虑将数据分块存储或使用其他持久化方案(如本地数据库)。
// 检查数据大小
const data = { key: 'value' };
const dataSize = JSON.stringify(data).length;
if (dataSize > 10 * 1024 * 1024) {
  console.error('数据过大,无法写入缓存');
}

3. 缓存键名冲突

如果缓存键名与其他数据冲突,可能导致读取时获取到错误的数据。

解决方法: 确保使用唯一的键名存储数据,避免冲突。

// 使用唯一键名
uni.setStorageSync('uniqueKey', JSON.stringify(data));

4. 异步读取缓存问题

如果使用异步方法读取缓存(如 uni.getStorage),可能在数据未完全写入时就进行了读取操作。

解决方法: 确保在写入完成后再进行读取操作,或使用同步方法(如 uni.getStorageSync)。

// 异步写入和读取
uni.setStorage({
  key: 'myData',
  data: JSON.stringify(data),
  success: () => {
    uni.getStorage({
      key: 'myData',
      success: (res) => {
        const parsedData = JSON.parse(res.data);
        console.log(parsedData);
      }
    });
  }
});

5. 数据类型问题

如果 JSON 数据中包含特殊数据类型(如 undefinedNaN 或函数),在序列化和反序列化时可能会丢失或出错。

解决方法: 确保 JSON 数据中仅包含可序列化的数据类型(如字符串、数字、数组、对象等)。

// 清理数据
const data = { key: 'value', invalid: undefined };
const cleanData = JSON.parse(JSON.stringify(data)); // 移除不可序列化的属性
uni.setStorageSync('myData', JSON.stringify(cleanData));

6. 编码问题

如果 JSON 数据中包含特殊字符或编码问题,可能导致读取时解析失败。

解决方法: 确保数据编码一致,并在必要时对数据进行编码或解码。


7. 缓存数据损坏

在某些情况下,缓存数据可能因存储异常或设备问题而损坏。

解决方法: 在读取缓存时添加异常处理,并在数据损坏时清除缓存。

try {
  const storedData = uni.getStorageSync('myData');
  const parsedData = JSON.parse(storedData);
  console.log(parsedData);
} catch (error) {
  console.error('缓存数据解析失败', error);
  uni.removeStorageSync('myData'); // 清除损坏的缓存
}
回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!