是,uni.navigateTo传参超长导致SyntaxError: Unexpected end of JSON input,根本原因是微信小程序对URL长度硬性限制约2048字符,超出后参数被截断,JSON.parse因字符串不完整而报错,需用encodeURIComponent编码后再JSON.stringify,接收端严格按decodeURIComponent→JSON.parse顺序解析。

uni.navigateTo 传参超长直接报 SyntaxError: Unexpected end of JSON input
这不是 uni-app 的 bug,而是小程序底层对 URL 长度的硬性限制——微信/支付宝等平台实际限制在约 2048 字符以内,超出后参数被截断,JSON.parse 就会因字符串不完整而抛出这个错误。
典型现象是:A 页面用 uni.navigateTo({ url: `/pages/detail?data=${JSON.stringify(obj)}` }) 传一个含 base64 图片或长文本的对象,B 页面 onLoad 中拿到的 options.data 是空字符串或半截字符串,JSON.parse 直接崩。
- 必须对参数做 URI 编码,否则空格、
?、&等字符会导致 URL 解析失败 -
JSON.stringify后再套一层encodeURIComponent,不是只编码 key 或只编码 value - 接收端必须严格按顺序:先
decodeURIComponent,再JSON.parse,顺序反了会解码失败 - macOS/Linux 下路径大小写敏感,
encodeURIComponent后的字符串若含大小写混用字段,要确保原始对象字段名一致
页面间传参超长时该用 globalData 还是 postMessage
两者适用场景完全不同,选错反而引入新问题。
globalData 适合「跳转前已知、生命周期内稳定」的数据,比如用户登录态、订单 ID、配置项。它本质是全局变量,多个页面读写同一引用,没有序列化开销,但无法解决跨分包通信(分包间 getApp() 拿不到主包 globalData 修改)。
postMessage 是为 web-view 或原生子窗体设计的异步通信机制,小程序普通页面间不能用;uni-app 的 uni.$emit/uni.$on 是事件总线,但页面销毁后监听器自动清除,不适合跳转传参这种一次性的强关联场景。
- 如果只是跳转前后两个页面通信,优先用 URL 编码方案,简单可控
- 若数据过大(如 >100KB 的富文本或图片数组),且不需要返回时回传,改用
uni.setStorageSync存临时键,目标页读完立刻uni.removeStorageSync - 分包页面间传参,绝对不要依赖
globalData,改用uni.navigateTo+ 编码,或通过主包中转(先跳主包页,再由主包页跳分包页并传参)
encodeURI 和 encodeURIComponent 的区别不能搞混
URL 中的 query 参数必须用 encodeURIComponent,不是 encodeURI。后者会放过 /、?、= 等分隔符,导致整个 URL 结构被破坏。
例如:encodeURIComponent('a&b=c?d') → 'a%26b%3Dc%3Fd',能安全拼进 URL;而 encodeURI('a&b=c?d') → 'a&b=c?d',& 和 ? 会被当成 URL 分隔符,后续参数全乱。
- 所有拼进
url字符串的值,都必须走encodeURIComponent -
JSON.stringify后的字符串本身可能含双引号、斜杠等,必须整体编码,不能只编码其中某一段 - 服务端若也参与解析,需确认其解码逻辑是否与前端
decodeURIComponent行为一致(标准 UTF-8)
tabBar 页面无法接收 URL 参数的隐性限制
小程序规定:通过 uni.switchTab 跳转的 tab 页面,onLoad 的 options 永远为空对象,无论你在 URL 里塞多少参数。这是底层限制,uni-app 无法绕过。
常见误操作:把商品详情页加进 tabBar.list,还想通过 /pages/detail?id=123 带参跳转,结果 options.id 总是 undefined。
- tab 页面只能靠
uni.getStorageSync或globalData传参,不能依赖 URL - 如果业务必须动态展示不同内容,改用非 tabBar 页面承载详情,或用
uni.reLaunch强制重置栈并带参跳转(注意这会清掉所有历史页) - 真要从 tabBar 页出发带参,只能先
uni.navigateTo到一个中间页,由中间页再uni.switchTab并通过globalData中转


















