活体检测需前后端协同完成,前端仅负责按规范采集多帧图像,后端调用云服务进行判定;小程序与H5摄像头逻辑、帧处理、上传方式及时间戳校验均须严格区分且符合服务商要求。

活体检测不是前端能独立完成的事
uni-app 本身不提供活体算法,也不具备实时分析人脸动作的能力。所谓“实现人脸识别活体检测”,本质是前端负责合规采集(带动作指令的多帧图像),后端调用阿里云/腾讯云/百度AI等已通过等保认证的服务完成比对与判定。你如果在 uni.chooseImage 拍一张照就往百度API发,大概率收到 LIVENESS_FAIL 或 NO_FACE_DETECTED —— 不是接口错了,是采集方式没满足服务要求。
小程序和 H5 必须分开写摄像头逻辑
微信小程序用 <camera> 组件,H5 用 navigator.mediaDevices.getUserMedia,二者 API 完全不兼容,强行统一会掉坑里:
- 小程序端:必须启用
mode="face",但注意onFaceDetect只返回检测状态(如"face_found"),不输出图像;真要抓帧得靠takePhoto主动调用,每 300ms 一次,连续 6 帧(眨眼动作最低要求) - H5 端:需用
canvas.getContext('2d').drawImage()手动截帧,且必须控制 canvas 尺寸(建议 640×480),否则压缩后仍超 200KB - 两者的帧率、自动曝光、对焦行为差异极大——小程序在暗光下容易过曝失真,H5 则可能因浏览器限制无法触发自动对焦
上传多帧图片时 formData 处理方式完全不同
uni.uploadFile 在小程序和 H5 对 formData 的处理逻辑相反,这是上线前最常翻车的一环:
- 小程序端:不支持直接 append base64 字符串。必须先用
uni.getFileSystemManager().writeFile写入临时文件,再把filePath传给formData - H5 端:可构造原生
FormData,但 base64 要转成 Blob:fetch('data:image/jpeg;base64,' + str).then(res => res.blob()),否则后端收不到二进制流 - 字段名必须严格匹配服务商要求:腾讯云要
image_list(数组),阿里云要image+image_type=FACE_LIVENESS,拼错一个字母就 400
最容易被忽略的时间戳问题
所有活体帧的时间戳必须落在合理范围内(比如前后不超过 3 秒),且不能是未来时间。如果你测试时看到错误里含 "INVALID_TIMESTAMP" 或干脆无响应,先检查系统时间——知识库明确记录过:有开发者在调试环境里把手机时间设成了 2026年5月1日,结果所有活体请求都被后端静默拒绝。这不是玄学,是多数合规服务强制校验客户端时间防止重放攻击。


















