ARTICLE · 1230230
uni-app扫普通二维码进小程序:微信文档没写的3个坑(附完整代码)
uni-app扫普通二维码进小程序:微信文档没写的3个坑(附完整代码)配置少一个斜杠、解码少一个判断、域名没有备案等,都会让功能“看起来配好了但就是不能用”。 线下门店做活动,每张宣传单上印一个二维码,用户扫码直接进小程序的对应门店页面,还要带上门店ID。 听起来很简单对吧?微信公众平台配置一下“扫普通链接二维码打开小程序”,写几行onLoad就完事。 但真上手了才发现,从配置到参数解析,每一步都藏着坑。🍂 登录微信公众平台,进入「管理」/「开发与服务」-「开发管理」-「开发设置」,在「服务器域名」/「业务域名」(看实际需求,我的小程序中还有其他功能,我用的是服务器域名)中配置二维码跳转链接的域名。 需要下载校验文件,放到域名根目录下完成验证。保存配置时会校验一次,确保服务器地址和你的服务器属于你。 这一步一般不会出问题,只要你有服务器权限,放个文件的事。 在开发设置页面下方找到「扫普通链接二维码打开小程序」模块,点击添加。 填写三样东西:二维码规则(域名拼上数据规则)、目标小程序页面路径、测试链接。 关键提醒:二维码规则最后面不能带/,注意,这是指二维码本身不能以/结尾。但后台配置的规则必须以/结尾才能支持子路径匹配。 这两个细节容易搞混。后台规则是https://example.com/shop/(以/结尾),生成的二维码是https://example.com/shop/?id=8。?后面的参数部分要求前缀匹配,规则以/结尾才能匹配到子路径。 域名必须配置过校验文件。小程序功能页面填哪个路径,就要在哪个路径的页面代码里接收参数。 
这里有开发版、体验版、线上版三个选项。 强烈建议采用 “开发版 → 体验版 → 线上版” 的渐进式测试流程。 先在“开发版”测试,功能稳定后提交“体验版”再次验证,最后一切无误再改为“线上版”并提交审核。 一旦审核通过,规则就对所有线上用户生效。如果解析代码有BUG,回滚配置非常麻烦。 特别注意:体验版只能固定测试链接里面配置的参数,不能动态传参。发布之后才能动态传任何参数。 这个坑很隐蔽。你在体验版测的时候参数都对,上线之后发现动态参数全丢了,因为体验版根本不支持。 用户扫码后,微信客户端将完整的扫描结果通过onLoad函数的options参数传递进来。但实际拿到的options有四种情况: 1、options.q(普通链接二维码)。 这是这篇的重点。options.q是一个经过编码的完整URL字符串,需要decodeURIComponent解码一次。 2、options.query.scene(小程序码)。 用户扫的是通过wxacode.getUnlimited接口生成的小程序码,参数藏在options.query.scene里,注意不是options.scene。两者结构完全不同,混用会漏数据。 3、options.code(直接进入)。 用户不是扫码,而是从其他页面跳转或直接打开,参数在顶层。 4、options为空。 首次进入但没有任何参数。 推荐一个健壮的解析函数,把四种情况都覆盖:1、decodeURIComponent报错 微信开发者工具模拟的scene是未编码的,但真机扫码一定是编码过的。 开发时测试通过,真机扫码直接URIError: URI malformed。 这个坑最典型的表现是:开发者工具里一切正常,真机扫码直接白屏或报错。 解决方案:加try/catch,或者先判断字符串是否包含%再决定是否解码。 💡 总结: 扫普通链接二维码进小程序这个功能本身不复杂。 📖 推荐阅读 ------ END ------ ✧ 持续分享 ✧ *深耕技术|持续迭代|温柔前行* #UniApp #小程序 #扫普通链接二维码 #onLoad #前端开发
🔧 第一步:配置业务域名
▲🔧 第二步:配置普通链接二维码规则
▲
🔧 第三步:选择测试范围并发布
▲📦 参数获取:onLoad里有四种情况
▲// 解析二维码URL中的参数function parseQRCodeParams(url) {const params = {}if (url.indexOf('?') !== -1) {const queryStr = url.split('?')[1]queryStr.split('&').forEach(item => {const [key, value] = item.split('=')params[key] = decodeURI(item.split('=')[1] || '')})}return params}// onLoad中统一处理onLoad(options) {let source = ''if (options.q) {source = 'qr'const decodedUrl = decodeURIComponent(options.q)options = parseQRCodeParams(decodedUrl)} else if (options.query && options.query.scene) {source = 'scene'options = parseQRCodeParams(decodeURIComponent(options.query.scene))}// 此时 options 里已经是解析好的参数了console.log('来源:', source, '参数:', options)}
🕳️ 我遇到的3个坑
▲function safeDecode(str) {try {return decodeURIComponent(str)} catch (e) {return str}}
2、参数前缀匹配失败
微信客户端扫码的匹配规则是:二维码链接的协议、域名与已配置的规则一致,二维码链接属于后台配置规则的子路径,参数需要前缀匹配。
后台配置的规则是https://example.com/shop/(以/结尾),生成的二维码是https://example.com/shop/?id=8。
?后面的参数部分要求前缀匹配。但很多人配置规则时忘了以/结尾,导致子路径匹配失败,扫码后不打开小程序。
后台规则以/结尾才能支持子路径匹配。 这个细节官方文档里没重点说,踩过一次才知道。
3、域名必须备案
生产版本必须使用已备案的HTTPS域名,这是硬性要求。
本地开发用ngrok或natapp做内网穿透测试可以,但上线前一定要换成备案域名。
没有备案的域名,开发版和体验版可能能跑,线上版直接不生效。这个坑最难排查,因为报错信息不会告诉你“域名没备案”。
复杂度全在细节里——配置规则少一个斜杠、解码时少一个判断、域名没有备案,都会让功能“看起来配好了但就是不能用”。
这篇文章的三个坑,是我排查了许久才总结出来的。
配置没问题不代表参数没问题,参数没问题不代表真机没问题,真机没问题不代表线上没问题。 每一步都要验证,每一步都可能藏着让你多花许久时间的细节。
希望你看完能少走弯路。
这篇的完整代码包我打包好了,关注后回复「扫码」,自动发你下载链接。
你在配置扫普通链接二维码时踩过什么坑?有没有遇到“开发版正常、体验版正常、线上版挂了”的情况?评论区聊聊👇
小鹿
2026.10.22
欢迎关注,一起迭代成长,解锁更多前端技巧 🦌















































































