H5如何拉起微信掃一掃
項(xiàng)目開發(fā)中有很多場(chǎng)景需要拉起微信掃一掃,在這里主要記錄下開發(fā)過程中遇到的一些問題,以及解決方案。僅供參考
官方api:
https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html
前端內(nèi)容:
1.npm下載 / 導(dǎo)入相關(guān)JS
npm install weixin-js-sdk在需要調(diào)用JS接口的頁(yè)面引入如下JS文件,(支持https):[http://res.wx.qq.com/open/js/jweixin-1.2.0.js](http://res.wx.qq.com/open/js/jweixin-1.2.0.js)2.引用(全局)main.js
import wx from "weixin-js-sdk";3.配置
1.從后端獲取參數(shù),通過config接口注入權(quán)限驗(yàn)證配置
WEIXIN_JSDK() {const url = encodeURIComponent(location.href.split("#")[0]); //獲取當(dāng)前頁(yè)面路由http.fetchGet(`后端接口$ {url}`).then(data = >{let a = data.data.data;wx.config({debug: false,// 開啟調(diào)試模式,調(diào)用的所有api的返回值會(huì)在客戶端alert出來,若要查看傳入的參數(shù),可以在pc端打開,參數(shù)信息會(huì)通過log打出,僅在pc端時(shí)才會(huì)打印。appId: a.appid,// 必填,公眾號(hào)的唯一標(biāo)識(shí)timestamp: a.timestamp,// 必填,生成簽名的時(shí)間戳nonceStr: a.noncestr,// 必填,生成簽名的隨機(jī)串signature: a.signature,// 必填,簽名jsApiList: ["scanQRCode", "getLocation"] // 必填,需要使用的JS接口列表});});},
2.調(diào)起掃一掃接口
wx.ready(function() {wx.scanQRCode({// 微信掃一掃接口desc: "scanQRCode desc",needResult: 1,// 默認(rèn)為0,掃描結(jié)果由微信處理,1則直接返回掃描結(jié)果,scanType: ["qrCode", "barCode"],// 可以指定掃二維碼還是一維碼,默認(rèn)二者都有success: function(res) {const getCode = res.resultStr; // 當(dāng)needResult 為 1 時(shí),掃碼返回的結(jié)果} else {}},fail: function(res) {Toast(res.errMsg);}});});
后端內(nèi)容:
1.獲取參數(shù)
public function renew() {//獲取ticket$ticket = $this->get_access_token($pay['app_id'],$pay['secret']);//生成JSSDK實(shí)例$opt['app_id'] = $pay['app_id'];$opt['jsapi_ticket'] = $ticket['ticket'];$opt['url'] = '此處填寫你的當(dāng)前地址url';$wx = $this->configuration($opt);$data['wx'] = $wx;return ajax_return($data,'成功',0);}public function get_access_token($appid,$secret) {//獲取已存儲(chǔ)d的token,token值2小時(shí)失效,需要自己存儲(chǔ)$token = DB::name('wxtoken')->value('token');//獲取ticket$get_jsapi_ticket = $this->get_jsapi_ticket($token);$get_jsapi_ticket = json_decode($get_jsapi_ticket,true);//如果token失效,就重新獲取if($get_jsapi_ticket['errcode'] == 40001 || $get_jsapi_ticket['errcode'] == 42001 ) {$get_url="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".$appid."&secret=".$secret;$data = $this->curl($get_url);$data = json_decode($data,true);DB::name('wxtoken')->where('id',1)->update(['token'=>$data['access_token']]);$get_jsapi_ticket = $this->get_jsapi_ticket($data['access_token']);}return($get_jsapi_ticket);}//獲取ticketpublic function get_jsapi_ticket($token) {$get_ticket_url="https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=".$token."&type=jsapi";$data = $this->curl($get_ticket_url);return($data);}//生成隨機(jī)字符串private function createNonceStr($length = 16) {$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";$str = "";for ($i = 0; $i < $length; $i++) {$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);}return $str;}//返回配置config數(shù)據(jù)public function configuration($option) {//簽名算法$timestamp=time();//時(shí)間戳$noncestr =$this->createNonceStr();//拼接$signature原型$ping="jsapi_ticket=".$option['jsapi_ticket']."&noncestr=".$noncestr."×tamp=".$timestamp."&url=".$option['url'];//加密生成signature$signature=sha1($ping);$signPackage = array("appID" => $option['app_id'],"noncestr" => $noncestr,"timestamp"=> $timestamp,"signature"=> $signature,"jsapi_ticket"=> $option['jsapi_ticket']);//返回參數(shù)return($signPackage);}
問題解決方法及原因
1.簽名失效
– 首先利用js校驗(yàn)工具
http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign 去校驗(yàn)下簽名是否正確
– 再確認(rèn)頁(yè)面url是否正確(location.href.split(‘#’)[0]),包括’http(s)://’部分,以及’?’后面的GET參數(shù)部分,但不包括’#’hash后面的部分
– appId是否正確,config 中的 appid 與用來獲取 jsapi_ticket 的 appid
以上是簽名失效的檢查順序,并且要確保項(xiàng)目開發(fā)的安全域名已經(jīng)在公眾號(hào)內(nèi)配置。
2.spa單頁(yè)面應(yīng)用,服務(wù)端渲染index頁(yè)面返回客戶端,本地頁(yè)面切換不存在服務(wù)端刷新,因此,在需要調(diào)起掃一掃的頁(yè)面?zhèn)鬟f的url與服務(wù)端url不一致,當(dāng)強(qiáng)制刷新頁(yè)面時(shí),服務(wù)端的url與當(dāng)前頁(yè)面一致,因此可以成功獲取。
解決方法 再進(jìn)入該頁(yè)面后強(qiáng)制刷新一次(reload)
當(dāng)然要要標(biāo)記下首次進(jìn)入才需要刷新,否則會(huì)造成很對(duì)不必要的刷新
3.ios的簽名要在入口頁(yè)獲取,解決了簽名失效的問題
其他
1.安卓在當(dāng)前頁(yè)面注入config,獲取簽名
2.公眾號(hào)確認(rèn)是否配置安全域名

