纯HTML5+js 实现二维码扫描及拍照上传

news/2024/11/8 15:32:34/

上头最近新提的需求,要求web端实现扫描识别二维码自动跳转页面,并且其他二维码扫描工具扫描出来的结果,与本站点扫描出来的结果不一样

首先分析需求,这种功能一般用于移动设备,PC用的比较少。与其他工具扫描结果不一样,则需要在获取扫描结果后,做相应的操作。

思路:1.生成二维码时,往数据库加入短地址(随机生成,可以是6位大小写英文)与长地址(加密,并生成生成一串MD5附加在后面)

2.获取二维码扫描结果后,首先对二维码中的短地址进行查询,找到对应的长地址,对长地址进行一系列的解密操作,解密过后得到对应的解密数据,并再次生成MD5,与长地址中的MD5进行对比,一致则进入下一步操作,不一致则说明长地址被篡改。验证当前登录用户与生成二维码的用户(长地址中获取)是否一致,必须一致才可以跳转(因为我这边扫描二维码得到的都是私人信息)否则私人信息可能被盗取。

这里就贴上调用摄像头的代码,至于加密解密,可自行百度

HTML代码

<a id="scan" href="javascript:void(0)">二维码扫描</a><div hidden="hidden"><div id="divQRScan"><div class="tab-content"><!-- 由于llqrcode.js中写死了id,所以id必须为qr-canvas --><video id="QRvideo" muted autoplay playsinline width="400" height="500"></video><canvas id="qr-canvas" style="display:none;"></canvas></div></div>
</div><script src="@Url.Content("~/Scripts/QRCodeScan/llqrcode.js")"></script>
<script src="@Url.Content("~/Scripts/QRCodeScan/QRScan.js")"></script>

javascript代码(QRScan.js)

const Scan = {videoInputDevice: [], //设备列表videoElement: document.getElementById("QRvideo"),canvasElement: document.getElementById("qr-canvas"),decodeTimer: null,canvasTimer: null,canvasContext: document.getElementById("qr-canvas").getContext("2d"),// 获取到的媒体设备gotDevices (deviceInfos) {let that = this;for (let i = 0; i !== deviceInfos.length; ++i) {let deviceInfo = deviceInfos[i];if (deviceInfo.kind === 'audioinput') {// 音频设备} else if (deviceInfo.kind === 'videoinput') {// 视频设备that.videoInputDevice.push(deviceInfo);} else {// 其他设备console.log('Found one other kind of source/device: ', deviceInfo);}}},getStream () {let that = this;if (window.stream) {window.stream.getTracks().forEach((track) => {track.stop();});}// if(that.isIOS){//     let constraints = {//         video: { facingMode: { exact: "environment" } }//       };//     console.log('3: ', constraints);//     // let constraints = {//     //   video: {//     //     // environment表示后置摄像头//     //     // user表示前置摄像头//     //     facingMode: ("environment")//     //   }//     // };// }else{let constraints = {// 包含audio 可声明音频设备调用// 声明视频设备调用// video: truevideo: {deviceId: {// [1].deviceId 表示后置摄像头,默认开启的是前置摄像头exact: that.videoInputDevice[1].deviceId}}};// }// 视频设备初始化navigator.mediaDevices.getUserMedia(constraints).then(that.gotStream.bind(that)).catch(that.handleError.bind(that));that.captureToCanvas();that.decode();},// 解码decode () {let that = this;try {qrcode.decode();} catch (e) {console.log('1:' + e);};that.decodeTimer = setTimeout(that.decode.bind(that), 100); // 解码频率为100毫秒一次},//将视频流放到画布captureToCanvas () {let that = this;try {// 根据视频大小设置canvas大小let w = that.videoElement.videoWidth;let h = that.videoElement.videoHeight;that.canvasElement.width = w;that.canvasElement.height = h;that.canvasContext.drawImage(that.videoElement, 0, 0, w, h);} catch (e) {console.log(e);};// 100毫秒绘制一次that.canvasTimer = setTimeout(that.captureToCanvas.bind(that), 100);},handleError (error) {$.colorbox.close();if (/Android|webOS|iPhone|iPod|BlackBerry/i.test(navigator.userAgent)) {if (error.toString().indexOf("TypeError: Cannot read property 'deviceId' of undefined") != -1) {alert("无法访问摄像头!请授予手机浏览器摄像头权限或切换至有摄像头权限的浏览器!");}} else {console.log(error);}return;},gotStream (stream) {let that = this;window.stream = stream; // make stream available to consolethat.videoElement.srcObject = stream;},isIOS() {var u = navigator.userAgent;var IOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端if (IOS) {return true;} else {return false;}},init () {let that = this;// API参考// https://developer.mozilla.org/zh-CN/docs/Web/API/MediaDevices/enumerateDevices// 先获取设备列表,方便调用后置摄像头let devices = navigator.mediaDevices.enumerateDevices().then(that.gotDevices.bind(that));document.querySelector('#scan').addEventListener('click', () => {$.colorbox({scrolling: true,overlayClose: true,reposition: false,innerWidth: "90%",innerHeight: "90%",maxWidth: "630px",maxHeight: "540px",inline: true,href: "#divQRScan"});that.videoElement.style.display = 'block';that.videoElement.play();devices.then(that.getStream.bind(that)).catch(that.handleError.bind(that));that.canvasContext.clearRect(0, 0, 300, 200);var hasRun = false; //避免重复执行回调函数//结果回调qrcode.callback = (e) => {if (!hasRun) {// 清除画布,停止摄像头                  clearTimeout(that.decodeTimer);clearTimeout(that.canvasTimer);that.canvasContext.clearRect(0, 0, 300, 200);if (window.stream) {window.stream.getTracks().forEach((track) => {track.stop();});}that.videoElement.style.display = 'none';that.canvasElement.style.display = 'none';e = e.replace("httq://", "http://").replace("httqs://", "https://"); //这里有时会把http识别为httq,可在这一步替换$.colorbox.close();if (e.indexOf("http://") != -1 || e.indexOf("https://") != -1) {hasRun = true;//这里可跳转到后台进行解密处理window.location.href = e;} else {hasRun = false;alert("扫描错误,请重试!");}}}});}};Scan.init();

llqrcode.js可在百度下载,也可评论邮箱索要,代码直接复制粘贴后稍微修改便可使用,用到了colorbox(此插件百度jquery colorbox下载即可)

拍照上传大同小异,不需要llqrcode.js,只是对canvs操作(canvasContext就是扫描获得的图像),网上也有不少拍照上传的插件,如有需要请至蓝奏云下载(仅提供llqrcode.js):https://wws.lanzoux.com/i6VpCg3kb3i

请大家不要再求源码了!!新建一个HTML页面,把上面的代码复制进去,相关的插件(colorbox,llqrcode.js)引用好(<script src=""></script>)运行即可,不会再报错!


http://www.ppmy.cn/news/769011.html

相关文章

图片预览(原生js实现)

功能描述 很多网站都是使用浏览器自带图片浏览功能&#xff0c;但看起来很low&#xff0c;想手动实现图片预览功能&#xff0c;点击图片弹出大图预览框在屏幕中间显示&#xff0c;根据图片宽高自适应屏幕大小 效果图 具体代码实现 页面preview.html <!DOCTYPE html> …

[Android] 通过Menu实现图片怀旧、浮雕、模糊、光照和素描效果

由于随手拍项目想做成类似于美图秀秀那种底部有一排Menu实现不同效果的功能,这里先简单介绍如何通过Menu实现打开相册中的图片、怀旧效果、浮雕效果、光照效果和素描效果.后面可能会讲述如何通过PopupWindow实现自定义的Menu效果. 希望文章对大家有所帮助,如果有错误或不足…

安卓端调用相机拍照返回并预览---清晰原图

安卓端调用相机拍照并返回预览图片 一、demo预览二、xml代码和activity简单代码描述。三、老规矩再来写几个转换工具方法 继之前写的安卓调用相机拍照返回预览&#xff0c;如果对于画质要求不高的话可以考虑之前的写的那篇&#xff0c;返回的是一个压缩后的bitmap &#xff0c;…

JavaScript进阶(八)JS实现图片预览并导入服务器功能

赠人玫瑰&#xff0c;手留余香。若您感觉此篇博文对您有用&#xff0c;请花费2秒时间点个赞&#xff0c;您的鼓励是我不断前进的动力&#xff0c;共勉&#xff01; 项目开发过程中&#xff0c;需要实现文件上传功能。借此机会学习之。 使用HTML中现有的input type “file”可以…

android图片特效处理之模糊效果

这篇将讲到图片特效处理的模糊效果。跟前面一样是对像素点进行处理&#xff0c;算法是通用的&#xff0c;但耗时会更长&#xff0c;至于为什么&#xff0c;看了下面的代码你就会明白。 算法&#xff1a; 一、简单算法&#xff1a;将像素点周围八个点包括自身一共九个点的RGB值…

解决H5调用安卓相机实现拍照并上传

最近在开发中遇到一个问题&#xff0c;要在APP内嵌的H5页面中实现拍照录像并上传到后端服务器。 刚开始我直接想到&#xff1a; <input type"file" accept"image/*" capture"camera"> 由于项目用vant UI&#xff0c;于是用了Uploader文…

mui 原生jsH5预览图片

mui 原生jsH5预览图片 下载mui.min.css&#xff0c;mui.js&#xff0c;mui.zoom.js&#xff0c;mui.imageViewer.js&#xff0c;mui.previewimage.js&#xff0c;app.js <link rel"stylesheet" href"./css/mui.min.css"> <script src"./js/…

html实现调取手机相机进行拍照上传——技能提升

今天同事问我一个我之前参与的项目&#xff0c;由于之前只做了样式&#xff0c;并没有书写功能&#xff0c;因此同事接手后需要做一个html实现手机拍照上传的功能&#xff1a; 由于项目是一个后台管理系统&#xff0c;使用的是vueant-design的框架&#xff0c;因此上传图片就是…