聊聊H5浏览器实现扫一扫
作者:互联网
我们开发了一款H5产品,原本是由小程序跳转进入的,结果客户因为域名未备案原因,导致产品无法在移动端使用。继而我们将程序嵌入APP,奈何客户方APP里面居然米有提供扫一扫接口导致产品无法使用。于是自己调研了一下怎样不借助平台自己实现扫一扫功能。找了相当多的资料,结果在某哥的文章中找到了解决方法,点此可看(掘金),在此也谢谢这位大神的文章,让我脱离苦海。接下来我讲下我的实现:
我们移动端用的是react
第一步引入插件zxing
cnpm i -S @zxing/library@0.15.1
此处注意,一定要使用0.15.x或者0.16.0版本,其他版本会报错
第二步,测试页面代码
import React, {useState, useEffect} from 'react';
import { Toast, Button } from 'antd-mobile';
import { BrowserQRCodeReader } from '@zxing/library';
// 此方法是为了兼容ios无法获取设备ID而写的
async function getVedioPermission(){
let m = await navigator.mediaDevices.getUserMedia({video:true, audio:true}).catch(function(){Promise.resolve(null)})
if(!m){
Toast.fail('获取权限失败,label 和 deviceId不显示',3);
}
let d = await navigator.mediaDevices.enumerateDevices();
// let str = ""
let did = '';
d.forEach(function(item) {
// str+=`kind: ${item.kind};\ngroupId: ${item.groupId}; \ndeviceId: ${item.deviceId}; \nlabel: ${item.label};\n`;
if (item.kind === 'videoinput') {
did = item.deviceId; // 获取最后一个视频设备的id(原则上最后一个是后置摄像头)
}
})
// alert(str); // 查看系统所有设备列表
return Promise.resolve(did);
}
function initReader(){
const codeReader = new BrowserQRCodeReader();
return codeReader.getVideoInputDevices()
.then(async videoInputDevices => {
if (videoInputDevices.length <= 0){
throw Error('没找到摄像头啊');
}
// 双摄的时候采用后置,否则采用第一个
let idid = videoInputDevices[videoInputDevices.length -1].deviceId || videoInputDevices[0].deviceId;
if (!idid) {
idid = await getVedioPermission();
}
return {
videoDeviceID: idid,
codeReader
}
})
.catch(err => {
console.log(err, 15);
})
}
function App() {
const [reader, setReader] = useState();
const [deviceID, setDeviceID] = useState();
const [message, setMessage] = useState();
const [result, setResult] = useState();
useEffect(() => {
(async function (){
if(!reader){
const {videoDeviceID, codeReader} = await initReader();
setReader(codeReader);
setDeviceID(videoDeviceID);
}
})()
}, [reader]);
const decode = (codeReader, selectedDeviceId) => {
codeReader.decodeFromInputVideoDevice(selectedDeviceId, 'video')
.then((result) => {
//console.log(result);
setResult(result.text);
}).catch((err) => {
alert(JSON.stringify(err));
setMessage(err.toString());
})
}
return <div className="App">
<div className="container" style={{textAlign:'center', width:'100%'}}>
<div>
<video id="video" width="200" height="200" style={{border: '1px solid gray', margin:'30px'}} />
<Button style={{margin:'30px'}} size="lg" color="primary" onClick={() => decode(reader, deviceID)}>扫一扫</Button>
</div>
</div>
<div>{result}</div>
<div>{message}</div>
</div>
}
export default App;
第三步,启动服务,切忌PC端测试的话要用localhost访问,否则无权限;
发布到服务器上使用的话,谨记需要https协议,否则也无权限访问。
不过根据资料显示IOS需要在safari版本在11之后的才支持,我没有测试
标签:function,const,扫一扫,H5,item,useState,result,codeReader,浏览器 来源: https://blog.csdn.net/sinat_28904949/article/details/120768130