报 SyntaxError: Unexpected end of JSON input 的根本原因是 URL 被截断导致 options.detailData 不完整,JSON.parse() 解析失败;各端 URL 长度有限(H5 约 2048 字符,微信小程序约 8192 字符),超长序列化字符串会被静默丢弃。

uni.navigateTo 传参超长时为什么报 SyntaxError: Unexpected end of JSON input
这不是 JSON 解析本身出错,而是 URL 被截断后,options.detailData 变成了一段不完整的字符串(比如只收到 {"title":"xxx),JSON.parse() 自然失败。根本原因是各端对 URL 长度有硬性限制:H5 约 2048 字符,微信小程序约 8192 字符,支付宝/百度小程序更低且不公开。一旦序列化后的字符串超过该阈值,浏览器或小程序引擎会静默丢弃超出部分。
用 encodeURIComponent(JSON.stringify(obj)) 编码能解决所有问题吗
能缓解,但不是万能解法:
- 编码后字符串长度只会增加(尤其中文、特殊字符),实际可用长度进一步压缩
- 若原始数据含大量 base64 图片或冗余字段,即使编码也极易突破上限
- 某些平台(如早期 iOS WebView)对 decodeURIComponent 的容错性差,半截编码串会导致解析崩溃
-
encodeURIComponent不处理undefined、函数、Date 对象等非 JSON 安全类型,JSON.stringify会将其转为null或忽略,可能引发逻辑错误
真正可靠的替代方案有哪些
优先绕过 URL 传参本身:
- 用
uni.$emit+uni.$on:跳转前触发事件,目标页onLoad中立即监听,适合单次、强关联的页面跳转 - 存入
getApp().globalData:在跳转前写入,目标页直接读取;注意多页并发时需加唯一 key 隔离,例如getApp().globalData['detail_123'] = data - 使用
uni.setStorageSync:把数据存本地,目标页读取后及时清理;适合需要持久化或跨进程场景(如从后台唤醒) - 改用接口拉取:只传 ID,目标页通过
uni.request再查详情;最稳妥,但增加一次网络请求
如果必须用 URL 传参,怎么最小化风险
做减法比做加法更有效:
- 只传必要字段:
this.list = res.data.map(item => ({ id: item.id, title: item.title })),砍掉图片 base64、日志字段、嵌套对象 - 避免深层嵌套:扁平化结构,
{ user: { name, avatar } }→{ userName, userAvatar } - 提前校验长度:
const str = JSON.stringify(data); if (str.length > 6000) console.warn('URL param too long'),便于定位问题源头 - 空值兜底:
onLoad(options) { try { this.data = JSON.parse(decodeURIComponent(options.data || '{}')) } catch(e) { this.data = {} } }


















