最近在业务上遇到一个问题:在一个H5页面中需要打开微信的扫码界面。在uni-app中,有原生的扫码方法,但是很遗憾的是,这个方法不支持H5。因此就需要用到微信的JSSDK了。
在网上找了一堆,给的方法也是五花八门。要么就是代码都是错的,要么就是没有后端代码。于是乎只能自己动手丰衣足食。
关于appid还有怎么安装JSSDK这些就不再赘述了,直接在uni-app的官网就能找到。我采用的方法是npm安装Jweixin-module。但是看DCloud论坛中有人说这样安装的话有一些模块已经过时了,因此或许可以尝试先npm安装Jweixin-moudle,之后将js替换成微信官方最新的。
由于JSSDK有严格的认证机制,因此需要进行服务端的配置。我直接使用的纯原生php来搭建的服务,因为自己的博客服务器用的不是thinkphp,而且这个认证功能也没有非常复杂,没必要杀鸡用牛刀,对于服务器本身就配置好了thinkphp框架或者flask 框架这些的,把代码改一下即可。
后端代码:
<?php header('access-control-allow-credentials:true'); header('access-control-allow-origin:'.$_SERVER['HTTP_ORIGIN']); header('Access-Control-Max-Age: 1800'); header('Access-Control-Allow-Methods:GET,POST,PUT,POST'); header('Access-Control-Allow-Headers:x-requested-with,content-type'); error_reporting(1); function guid() //生成随机字符串nonceStr用 { if (function_exists('com_create_guid')) { return com_create_guid(); } else { mt_srand((double)microtime() * 10000); $charid = md5(uniqid(rand(), true)); $uuid = substr($charid, 0, 8) . substr($charid, 8, 4) . substr($charid, 12, 4) . substr($charid, 16, 4) . substr($charid, 20, 12); return $uuid; } } function curl_get($url){ //get方法,用于获取accessToken和Jsapi-token //初始化 $curl = curl_init(); //设置抓取的url curl_setopt($curl, CURLOPT_URL, $url); //设置头文件的信息作为数据流输出 // curl_setopt($curl, CURLOPT_HEADER, 1); //设置获取的信息以文件流的形式返回,而不是直接输出。 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); //执行命令 $data = curl_exec($curl); // echo curl_getinfo($curl, CURLINFO_HTTP_CODE); //输出请求状态 curl_close($curl); return $data; } function renewTicket(){ //获取Jsapi-token try { $accessJson = json_decode(curl_get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET")); //此处补上你的appid和appsecret $accessToken = $accessJson->access_token; $ticketJson = json_decode(curl_get("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" . $accessToken . "&type=jsapi")); $ticketdata = array(); $ticketdata["ticket"] = $ticketJson->ticket; $ticketdata["exp"] = time() + $ticketJson->expires_in; $ticketFile = fopen('__Tickets', 'w'); //**重要** 请自行将__Tickets更名为随机字符串或不易被猜测的文件名,下同,另请注意Linux的读写权限分配,否则会出现无法写入新的tickets的情况 $ToWrite = json_encode($ticketdata); fwrite($ticketFile, $ToWrite); fclose($ticketFile); return $ticketJson->ticket; }catch (Exception $e){ echo $e; } } function GetJsapi(){ $ticketfile = fopen('__Tickets',"r"); $tickets = json_decode(fread($ticketfile,filesize('__Tickets'))); fclose($ticketfile); if(time()<$tickets->exp){ return $tickets->ticket; }else{ return renewTicket(); } } $jsapi_ticket = GetJsapi(); $timestamp = time(); $nonce = guid(); $url = $_GET["url"]; $ret = array(); $ret["timestamp"] = $timestamp; $ret["nonceStr"] =$nonce; $tmpStr = "jsapi_ticket=".$jsapi_ticket.'&noncestr='.$nonce."×tamp=".$timestamp.'&url='.$url; $tmpStr = sha1($tmpStr); $ret["signature"] = $tmpStr; echo json_encode($ret);
服务器的返回是一个json格式:
{ "timestamp":1616332427, "nonceStr":"e5a4f4994472631a9f7299e358449fd9", "signature":"9d85562617da3bf9ed729005079ab91f3d845556" }
在uni-app端,在onLoad()
下,先向服务器请求签名:
async getsign(){ this.url = location.href.split('#')[0] uni.request({ url:"你的服务地址", method:"GET,", data:{ "url":this.url }, success:((res)=>{ console.log(res.data), this.retdata = res.data; }) }) }
之后进行config:
jweixin.config({ debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId: "APPID", // 必填,公众号的唯一标识 timestamp: this.retdata.timestamp , // 必填,生成签名的时间戳 nonceStr: this.retdata.nonceStr, // 必填,生成签名的随机串 signature: this.retdata.signature,// 必填,签名 jsApiList: ['scanQRCode'] // 必填,需要使用的JS接口列表 }), jweixin.ready(function(){ jweixin.checkJsApi({ jsApiList: ['scanQRCode'], // 需要检测的JS接口列表,所有JS接口列表见附录2, success: function(res) { console.log("success"+res); }, fail: function(res){ console.log("fail"+res); } }); }) , jweixin.error(function(res){ // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。 console.log(res,'接口验证失败') });
之后就可以进行操作了,例如我这里需要用的扫码:
scanqr(){ var jweixin = require('jweixin-module'); jweixin.scanQRCode({ needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果, scanType: ["qrCode","barCode"], // 可以指定扫二维码还是条形码,默认二者都有 success: function (res) { // 要做的事情 } }); }
Comments | NOTHING