encodeURIComponent是唯一正确选择,因其彻底编码参数值中所有特殊字符(如&、=、空格),避免URL结构被破坏;而encodeURI保留结构符,拼接后会导致参数截断。

必须对参数值单独调用 encodeURIComponent,不能拼完再整体编码,也不能用 encodeURI —— 否则中文、&、=、空格等都会被错误截断或双重编码。
为什么 encodeURIComponent 是唯一正确选择
URL 中的 & 和 = 是结构分隔符,如果参数值里自带这些字符(比如商品标题 “iPhone 15 & Pro” 或用户 remark “上线了 = OK”),不编码就会破坏 query string 结构。浏览器和小程序解析时会把第一个 & 当作新参数起点,导致 options.title 只拿到 “iPhone 15 ”,后面全丢。
encodeURI 不处理 &、=、+ 等字符,只编码空格和非 ASCII;而 encodeURIComponent 编码更彻底,适合单个参数值。
- 错:
encodeURI('/pages/detail?title=iPhone 15 & Pro')→&仍保留,解析失败 - 对:
`/pages/detail?title=${encodeURIComponent('iPhone 15 & Pro')}`→&变成%26,安全 - 错:先
JSON.stringify(obj)再encodeURIComponent整个 query 字符串 →?、=也被编码,路由无法识别
onLoad 接收端必须 decodeURIComponent + JSON.parse 两步走
小程序和 App 环境不会自动解码 URL 参数,H5 虽然部分自动解,但行为不一致,必须统一手动处理。尤其当传的是对象字符串时,跳过 decodeURIComponent 直接 JSON.parse 会报错:SyntaxError: Unexpected token % in JSON at position 0。
常见错误现象包括:options.data 是 "%7B%22name%22%3A%22%E5%BC%A0%E4%B8%89%22%7D" 这种,而不是 "{"name":"张三"}"。
- 接收端必须写:
const raw = decodeURIComponent(options.data || '') - 再做:
const obj = JSON.parse(raw) - 永远加
try/catch,真机静默失败很常见,不打日志根本不知道卡在哪一步 - 别假设
options.data一定存在——网络抖动、冷启动、从分享卡片进入都可能导致为空
大对象或含图片路径的参数别硬塞 URL
微信小程序 URL 长度实际限制约 2KB,超过后安卓某些机型会直接截断,iOS 可能降级为白屏。像 /static/avatar.png 这种路径传参,一旦含空格或中文,不编码就是 404;编码后体积膨胀,更容易超限。
更稳的做法是改用缓存 + key 传递:
- 跳转前:
uni.setStorageSync('page_data_123', { name: '李四', avatar: '/static/avatar.png' }) - 跳转时只传轻量 key:
url: '/pages/detail?id=123' - 目标页
onLoad中:const data = uni.getStorageSync('page_data_123'),用完可removeStorageSync - 注意 key 命名要带业务前缀,避免冲突;大量数据建议用
uni.setStorage(异步)+ 回调兜底
Base64 编码不是银弹,但适合跨平台强一致性场景
当你的应用要同时跑在微信小程序、支付宝小程序、H5、App,且参数含大量特殊符号(比如 AI 返回的 Markdown 文本、嵌套 URL),encodeURIComponent 在不同平台对某些 Unicode 字符(如 emoji、生僻汉字)的处理仍有细微差异。这时 Base64 是更保守的选择。
它不依赖平台 URI 实现,只做字符映射,结果完全一致。但代价是体积增大 ~33%,且不能直接用于 URL 键名(如 ?base64=xxx 可以,?xxx=yyy 不行)。
- 编码:
btoa(unescape(encodeURIComponent(jsonStr)))(兼容老环境)或直接用Buffer.from(jsonStr).toString('base64')(Node / 新版 runtime) - 解码:
JSON.parse(decodeURIComponent(escape(atob(options.base64)))) - 仅建议用于关键路径(如分享卡片、支付回调参数),日常跳转优先用
encodeURIComponent
最易被忽略的一点:编码和解码必须严格一一对应。前端多调一次 encodeURIComponent,后端少解一次,或者 H5 自动解了一次而小程序没解,都会导致乱码。所有参数流转环节都要明确“谁负责编码、谁负责解码、是否可能被中间层(如 Nginx、CDN)二次处理”。











