<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          如何優(yōu)雅的在 H5 網(wǎng)頁中實現(xiàn)掃碼功能

          共 4373字,需瀏覽 9分鐘

           ·

          2022-05-27 23:28

          大廠技術??高級前端??Node進階

          點擊上方?程序員成長指北,關注公眾號

          回復1,加入高級Node交流群

          之前在做的項目中需要實現(xiàn)一個掃碼錄入的功能,具體效果就是在點擊掃碼按鈕后調(diào)取攝像頭,掃描條形碼將解碼后的數(shù)據(jù)填入到輸入框中。相信這個功能在日常的手機使用中,是非常常用的,下面來看看我是如何一步一步踩坑實現(xiàn)的吧

          ?? 內(nèi)容搶先看

          1. 采用 Quagga 庫實現(xiàn)遇到的問題和瓶頸
          2. 接入微信 SDK 的踩坑指北
          3. 最終解決方案
          一、掃碼初探 Quagga
          第一次接觸到掃碼的業(yè)務,一切都是全新的,也不知道從哪里開始,先到各個社區(qū)搜索了一下

          當時的搜索詞大概是這樣,得到結(jié)果就是利用 HTML5 中提供的 API 去實現(xiàn),然后又看到了 QuaggabarCode 等庫,在 npm 上查看了官方描述后,我覺得 Quagga 這個庫可能更符合這個項目的需求,因此對 Quagga 進行了一番研究 Quagga

          這個庫的使用并不難,首先需要引入 Quagga 這個庫

          yarn?add?quagga

          由于我是在 React 項目下開發(fā)的,因此我們需要在 returnJSX 內(nèi) 添加一個 DOM 節(jié)點,用來定制攝像頭打開攝像頭影像的投放區(qū)域

          代碼中的 yourElement ?節(jié)點就是用來做攝像頭的影像投放的

          接下來,需要開始使用 Quagga ,大概就是調(diào)一下方法,配置一下解碼方式,掃碼區(qū)域,然后就能喚起攝像頭,進行掃碼,再處理一下掃碼結(jié)果。由于初學,對它具體的代碼書寫還不是很熟悉,因此看老外敲了一晚的代碼,并在一個大佬的 github 倉庫內(nèi),找到了一個開源的掃碼錄入項目 ??????

          看了看它的實現(xiàn)代碼,然后開始了我的踩坑

          首先我們需要初始化 Quagga

          需要定制一下我們的解碼方式,對于我們需要掃描的碼是什么類型的,可以找個檢測網(wǎng)站測一下,我的是 Code39 類型的

          Quagga.init({
          ??inputStream:?{
          ????name:?"Live",
          ????type:?"LiveStream",?//?方式
          ????constraints:?{
          ??????width:?'790',
          ??????height:?'490'
          ????},?//?解碼區(qū)域
          ????numberOfWorkers:?navigator.hardwareConcurrency,
          ????target:?document.querySelector('#barcodeScan')?//?影像輸出到的節(jié)點
          ??},
          ??locate:?true,
          ??decoder:?{
          ????readers:?["code_39_reader"]?//?解碼方式
          ??}
          },?function?(err)?{
          ??if?(err)?{
          ????return?
          ??}
          ??Quagga.start()?//?開啟
          })
          Quagga.onDetected(this.onDetect)

          當成功掃碼后會調(diào)用 onDetected 方法,這就有點像生命周期一樣,都是定義好的,我們可以在這個函數(shù)里接收到返回來的 result 獲取到 codeResult 掃描結(jié)果

          onDetect(res){
          ??//?console.log(res.codeResult.code)
          ??Quagga.stop()
          ??Quagga.offProcessed()
          ??console.log(res.codeResult);
          }

          然后我們就可以開始瘋狂的掃碼,測試,經(jīng)過了一晚上的測試,我發(fā)現(xiàn)它并不能像別人視頻中那樣流暢準確的進行解碼,基本上輸出的結(jié)果沒幾個是對的上的,因此此路行不通,開始萌生了放棄的想法,后來發(fā)現(xiàn)可以直接調(diào)取微信的掃碼功能,來實現(xiàn)我們的需求,因此開始了微信 SDK 踩坑之路

          二、大戰(zhàn)微信 SDK
          在經(jīng)歷了 quagga 的失利后,開始了搗鼓接入微信 SDK 來實現(xiàn),先我們需要引入 weixin-js-sdk ,這樣我們就可以使用一些 wx 官方 API,比如這里需要使用到 scanQRcode
          在這里我們調(diào)用這個 API,它接收一個配置對象,具體可以看官方文檔
          比較重要的就是 needResult 它決定掃碼的結(jié)果由誰來處理,如果是 0 ,則由微信處理,例如掃取一個快遞碼,它在掃描結(jié)束后會跳轉(zhuǎn)到對應的頁面去,這不是我們想要的,因此設置為 1,會直接返回掃描的結(jié)果,我們可以在 success 回調(diào)中獲取到這個結(jié)果 resultStr ,這個 resultStr 是一個數(shù)組,第一項是掃碼的類型,第二項是解碼后的值,因此我們處理一下
          wx.scanQRCode({
          ????needResult:?1,?//?默認為0,掃描結(jié)果由微信處理,1則直接返回掃描結(jié)果,
          ????scanType:?["qrCode",?"barCode"],?//?可以指定掃二維碼還是一維碼,默認二者都有
          ????success:?function?(res)?{
          ????????let?result?=?res.resultStr.split(',')[1];?//?當needResult?為?1?時,掃碼返回的結(jié)果
          ????},
          ????fail:?function?(err)?{
          ????????console.log('error');
          ????????console.log(err);
          ????}
          })

          這樣我們一個簡單的掃碼功能就寫好了,真是很方便,只需要綁定到事件處理回調(diào)即可被調(diào)用。真的是這么簡單嗎?

          由于我們使用的是微信開放能力,我們需要進行配置,采用官方提供的 wx.config

          需要配置我們的 appId,以及一個簽名還需要配置我們需要使用的 API

          wx.config({
          ????debug:?false,?//?開啟調(diào)試模式,調(diào)用的所有api的返回值會在客戶端alert出來,若要查看傳入的參數(shù),可以在pc端打開,參數(shù)信息會通過log打出,僅在pc端時才會打印。
          ????appId,?//?必填,公眾號的唯一標識
          ????timestamp,?//?必填,生成簽名的時間戳
          ????nonceStr,?//?必填,生成簽名的隨機串
          ????signature,//?必填,簽名
          ????jsApiList:?["scanQRCode"]?//?必填,需要使用的JS接口列表
          });

          簽名這些配置項,需要后臺哥哥返回,我們需要向后端傳遞我們當前的 url,用來生成掐滅

          注意:一定是需要動態(tài)的,寫死了會有 bug

          這樣我們調(diào)用接口,后端返回幾個參數(shù)即可

          const?data?=?await?getWxKey({?url:?window.location.href.split('#')[0]?})

          這里有幾個需要注意的問題

          1. 調(diào)取微信 API 需要使用 access_token 這個需要后端去獲取,怎么解決我也不清楚,應該是通過 微信公眾號的 addId 去申請的
          2. 向后端傳遞的 url ,是需要通過動態(tài)獲取的,不然可能會有 invalid signature 簽名錯誤的情況

          在代碼層面上,我們能做的就是這些了,前端的代碼邏輯沒有很多,都是 API 調(diào)用,完整代碼如下

          const?openCamera?=?async?()?=>?{
          ????const?data?=?await?getWxKey({?url:?window.location.href.split('#')[0]?})
          ????const?{?appId,?timestamp,?nonceStr,?jsKey:?signature?}?=?data.data
          ????wx.config({
          ????????debug:?false,?//?開啟調(diào)試模式,調(diào)用的所有api的返回值會在客戶端alert出來,若要查看傳入的參數(shù),可以在pc端打開,參數(shù)信息會通過log打出,僅在pc端時才會打印。
          ????????appId,?//?必填,公眾號的唯一標識
          ????????timestamp,?//?必填,生成簽名的時間戳
          ????????nonceStr,?//?必填,生成簽名的隨機串
          ????????signature,//?必填,簽名
          ????????jsApiList:?["scanQRCode"]?//?必填,需要使用的JS接口列表
          ????});
          ????wx.ready(()?=>?{
          ????????wx.scanQRCode({
          ????????????needResult:?1,?//?默認為0,掃描結(jié)果由微信處理,1則直接返回掃描結(jié)果,
          ????????????scanType:?["qrCode",?"barCode"],?//?可以指定掃二維碼還是一維碼,默認二者都有
          ????????????success:?function?(res)?{
          ????????????????let?result?=?res.resultStr.split(',')[1];?//?當needResult?為?1?時,掃碼返回的結(jié)果
          ????????????????form.setFieldsValue({?orderNumber:?result?})
          ????????????},
          ????????????fail:?function?(err)?{
          ????????????????console.log(err);
          ????????????}
          ????????})
          ????})
          }

          但是寫到這里,我們的掃碼功能仍然是不可用的,我們還需要在微信公眾平臺來配置我們的接口域名,不然得到的會是 ??????

          我們需要在微信公眾平臺配置 JS 接口安全域名

          這樣我們的問題就能迎刃而解,在配置安全域名的時候,注意訪問的域名不要啟動代理,不然會綁定不成功


          至此我們的需求得以完成,文章可能看起來很容易,但是實際操作起來會用很多各種各樣的問題,希望這篇文章能夠幫助到有類似需求的你

          小tips:遇到問題的時候可以嘗試在微信交流平臺找答案,或者可以查看官方文檔

          最后,可能在很多地方講訴的不夠清晰,請見諒

          ?? 如果文章有什么錯誤的地方,或者有什么疑問,歡迎留言,也歡迎私信交流

          Node 社群



          我組建了一個氛圍特別好的 Node.js 社群,里面有很多 Node.js小伙伴,如果你對Node.js學習感興趣的話(后續(xù)有計劃也可以),我們可以一起進行Node.js相關的交流、學習、共建。下方加 考拉 好友回復「Node」即可。



          如果你覺得這篇內(nèi)容對你有幫助,我想請你幫我2個小忙:

          1. 點個「在看」,讓更多人也能看到這篇文章
          2. 訂閱官方博客?www.inode.club?讓我們一起成長

          點贊和在看就是最大的支持

          瀏覽 139
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  在线免费高清无码 | 天天操天天摸天天爱 | 人人操人人插人人摸人人爽人人 | 日韩无码视频网站 | 特级无码一区二区三区 |