根本原因是url query string中的特殊字符未编码,导致小程序解析时参数截断或混淆;必须对整个query value调用encodeuricomponent,接收端用decodeuricomponent解码后再json.parse。

uni.navigateTo 传参含 &、空格、中文时页面 onLoad 报 SyntaxError
根本原因是 URL query string 里的特殊字符没被编码,导致小程序解析 URL 时提前截断或混淆参数边界。比如 name=张三&v=1 会被当成两个独立参数 name=张三 和 v=1,但 张三 本身未编码,真机下直接丢弃,option 对象里只剩 { v: "1" },后续 JSON.parse(option.item) 就因字符串缺失而报 SyntaxError: Unexpected end of JSON input。
必须对整个 query value 做 encodeURIComponent,而不是只 encode 中文部分:
- ❌ 错误:直接拼接
url=`/page?data=${obj}`(obj 是对象或含特殊字符的字符串) - ✅ 正确:先
const encoded = encodeURIComponent(JSON.stringify(obj)),再url=`/page?data=${encoded}` - ⚠️ 注意:
encodeURIComponent会编码/和:,所以不能对整条 URL 调用它;只编码 query value 部分
接收端 decodeURIComponent 后 JSON.parse 失败
常见于传的是 JSON 字符串但解码后仍有残留转义或截断。比如服务端返回的字符串本身已含双引号、反斜杠,前端再套一层 JSON.stringify 就容易嵌套出错。
推荐写法(发送端):
const payload = { name: "李四", remark: "上线了 & 测试中" }
const url = `/pages/detail/detail?item=${encodeURIComponent(JSON.stringify(payload))}`
uni.navigateTo({ url })
接收端(onLoad):
onLoad(options) {
try {
const raw = decodeURIComponent(options.item)
const data = JSON.parse(raw) // 这里才真正解析
console.log(data) // { name: "李四", remark: "上线了 & 测试中" }
} catch (e) {
console.error('parse fail:', e, options.item) // 加日志,方便定位是 encode 还是 parse 阶段出问题
}
}
- 不要跳过
try/catch—— 真机环境下静默失败很常见 - 如果参数来自接口,建议服务端直接返回已编码字符串,避免前端拼接出错
-
options是字符串对象,options.item本身就是字符串,不需要再toString()
图片路径或文件路径作为参数传递时显示乱码
典型场景:把 /static/avatar/用户头像.png 当作路由参数传过去,结果接收端得到的是 /static/avatar/%E7%94%A8%E6%88%B7%E5%A4%B4%E5%83%8F.png 但没解码,渲染时路径失效。
关键点:路径参数和业务数据参数处理逻辑一致,都要走 encodeURIComponent → 传参 → decodeURIComponent 解码。
- 发送页:
url=`/pages/view/view?imgPath=${encodeURIComponent('/static/avatar/用户头像.png')}` - 接收页:
this.imgSrc = decodeURIComponent(options.imgPath) - ⚠️ 切忌在接收端直接用
options.imgPath渲染,那只是原始编码字符串 - 如果路径含
#或?,它们在 URL 中有特殊含义,必须编码,否则会被浏览器或小程序引擎截断
为什么 H5 正常、小程序真机报错
H5 端 URL 解析较宽松,能容忍未编码的中文或空格;小程序引擎(尤其微信)严格遵循 RFC 3986,遇到非法 URI 字符直接丢弃后续内容,且不报明显错误,只留白或静默失败。
- 开发者工具模拟的是宽松环境,不能代表真机行为
- macOS/Linux 下路径大小写敏感,
/Static/和/static/是不同路径,编码后也不同,务必统一 - 最稳妥的做法:所有动态拼接进 URL 的字符串,一律过
encodeURIComponent;所有从options拿到的参数,一律过decodeURIComponent
真正容易被忽略的不是“要不要编码”,而是“什么时候该编码整个值、什么时候只编码一部分”——只要它会出现在 ?key=value 的 value 位置,就必须整段编码。











