uni.scancode 扫不出码或报错主因是权限、平台限制和调用时机:h5不支持;app需相机权限及manifest配置;小程序需基础库版本达标且路径配置正确;应避免onload立即调用,改用按钮触发。

uni-app 中 uni.scanCode 为什么扫不出码或直接报错?
大部分问题出在权限、平台限制和调用时机上。uni.scanCode 在 H5 端根本不可用(浏览器无原生扫码能力),App 端需确保已申请摄像头权限,小程序端则依赖微信/支付宝等宿主环境是否开放扫码接口。
常见错误现象:fail sys permission denied(App 未授权)、fail not supported(H5 调用)、fail cancel(用户主动退出但没做容错处理)。
- App 端必须在
manifest.json中勾选「相机」权限,iOS 还需在ios → permissions下补充cameraUsageDescription描述 - 微信小程序需确认基础库版本 ≥ 1.7.0,且页面路径已配置在
app.json的requiredBackgroundModes(仅部分场景需要) - 不要在
onLoad中立刻调用 —— 尤其是 App 端,建议加个按钮触发,避免页面未就绪或权限弹窗未响应
想自己控制摄像头画面并实时识别二维码,该用 uni.chooseImage 还是 uni.createCameraContext?
二者完全不是一回事:uni.chooseImage 是选相册/拍照后返回图片临时路径,适合「拍完再识别」;而真·实时扫码必须用 uni.createCameraContext + 自定义 canvas 渲染 + 第三方解码库(如 jsqr)。
注意:uni.createCameraContext 仅支持 App 和微信小程序(基础库 ≥ 2.7.0),H5 仍不可行。
- App 端可用,但需手动处理视频流帧捕获、canvas 绘制、定时采样,性能差时容易卡顿
- 微信小程序中,
camera组件的bindcameraprocess事件可获取帧数据(需开启device-position="back"和flash="off") - 别直接用
ctx.takePhoto频繁截图 —— 容易触发系统限频,推荐每 300–500ms 主动 drawImage 一次到离屏 canvas 再解码
jsqr 解码失败率高,是不是参数没设对?
是。默认参数只适配高对比度、正向、无畸变的二维码,实际扫码场景中倾斜、反光、模糊、小尺寸都会导致 jsqr 返回 null。
关键参数要调整:maxQuality(默认 false,设为 true 可提升小码识别率)、inversionAttempts(默认 "dontInvert",遇到白底黑码建议设为 "attemptBoth")。
- 输入 canvas 尺寸不宜过大 ——
jsqr是纯 JS 实现,1080p 图像解码可能超 200ms,建议缩放到 640×480 或更小 - 务必检查 canvas 的
toDataURL("image/png")是否能正常导出 —— 若返回空字符串,说明 canvas 没正确绘制视频帧(常见于跨域图像或未 wait for camera ready) - 识别前先简单灰度+二值化预处理(可用
ctx.getImageData手动处理),比纯依赖jsqr内置逻辑更可控
App 端扫码后跳转失败或返回值丢失,uni.scanCode 的 success 回调里要注意什么?
回调里的 result 字段不是 always 存在 —— 微信小程序返回 result,App 端(尤其是 iOS)可能返回 scanType + charSet + content,而 content 才是真正扫码结果。
更麻烦的是:App 端扫码成功后若立即调用 uni.navigateBack,某些安卓机型会 crash;微信小程序中若在扫码回调里调 uni.switchTab,可能被拦截。
- 永远用
res.content || res.result取值,不要只读result - App 端扫码后如需跳转,加
setTimeout(() => { ... }, 100)延迟执行,避开 native 层资源释放冲突 - 扫码失败不要静默 ——
fail回调里至少uni.showToast({ title: "扫码失败", icon: "none" }),否则用户不知道发生了什么
uni.scanCode 测试没问题,上线后 H5 用户全卡在按钮点击无反应。真要覆盖 H5,只能引导用户用手机自带相机扫描,再通过 URL Scheme 或 Universal Links 跳回,这已经超出 uni-app 能力边界了。











