zoukankan      html  css  js  c++  java
  • jsapi微信扫一扫

    微信公众号开发--微信JS-SDK扫一扫功能

    首先请阅读微信JS-SDK说明文档,了解微信JS的相关说明。 
    根据官方的使用步骤,关键的有以下几步

    1. 绑定域名(很关键
    2. 引入JS文件(很简单)
    3. 通过config接口注入权限验证配置(很重要
    4. 通过ready接口处理成功验证(还没用到)
    5. 通过error接口处理失败验证(还没用到)

    绑定域名

    1首先到微信公众号设置里面添加js安全域名

    比如我的域名是带有二级目录的:dev.xxx.com/muyang

    那么在填入的时候域名为:dev.xxx.com/muyang

    2.扫码调用页面时提交的url地址,一定要跟扫码页面的url保持一直,多或者少一个“/”都不行

    例如,我扫码页面地址:dev.xxx.com/muyang/cat/

    那么提交给签名的url地址也必须要是: dev.xxx.com/muyang/cat/

    否则会报错:

    {“errMsg”:”config:invalid SignPackage”}
    

      

    所以,域名配置的时候一定要注意 
    1. 域名不要以http:开头 
    2. 域名不要配置到具体的页面 
    配置成功的提示如下

    开发:

    1,在页面引入:<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>

    并且开启debug: true,bug提示模式

    jsApiList:调用为扫码模块:scanQRCode

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>行李查询</title>
        <!-- Tell the browser to be responsive to screen width -->
        <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
        <!-- Bootstrap 3.3.7 -->
    
       <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
    
        <style>
    
            html,body{
                height:100%;
                font-size:14px;
                font-family:"Microsoft YaHei","Helvetica",sans-serif
            }
            .login-box-body, .register-box-body {
                90%;
                background: #fff;
                padding: 20px;
                border: 1px #D5D5D5 solid;
                color: #666;
                -webkit-border-radius: 5px;
                -moz-border-radius: 5px;
                border-radius: 5px;
                margin: 0 auto;
    
            }
    
            .login-box, .register-box {
                 360px;
                position: absolute;
                left: 50%;
                margin-left: -180px;
                top: 50%;
                margin-top: -200px;
                text-align: center;
            }
            .login-logo{
                padding-right:20px;
                background:url("<?php echo $base_url;?>/images/sao.png") no-repeat scroll left center transparent;
                height: 30px;
    
                padding-left: 35px;
            }
    
            * {
                -webkit-box-sizing: border-box;
                -moz-box-sizing: border-box;
                box-sizing: border-box;
            }
    
            a,a:link{
                text-decoration: none;
                color: #808080; }
    
    
            .col-xs-12{100%}
    
            .has-feedback img{
                150px;height:50px;
            }
        </style>
    
    </head>
    
    <body class="hold-transition login-page " style="background:url(<?php echo $base_url;?>img/loginbg.png) left top no-repeat;background-size:cover;overflow:hidden;position:relative">
    <div class="login-box ">
    
        <!-- /.login-logo -->
        <div class="login-box-body ">
            <div class="login-logo " style="color:#4f4f4f;font-size:20px;position:relative; color: #808080;">
                <a id="scanQRCode" url="<?php echo $base_url;?>/index/result">扫一扫行李牌条形码查询</a>
            </div>
    
    
            <!-- /.login-box-body -->
        </div>
        <!-- /.login-box -->
    </div>
    <div id="wm_id"></div>
    <!-- jQuery 2.2.3 -->
    
    <script>
        wx.config({
            debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
            appId: '<?php echo $jsApi['appId'];?>', // 必填,公众号的唯一标识
            timestamp: '<?php echo $jsApi['timestamp'];?>', // 必填,生成签名的时间戳
            nonceStr: '<?php echo $jsApi['nonceStr'];?>', // 必填,生成签名的随机串
            signature: '<?php echo $jsApi['signature'];?>',// 必填,签名,见附录1
            jsApiList: ['scanQRCode'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
        });
    
    
    // wx.error(function(res) {
        //     alert("出错了:" + res.errMsg);
        // });
    
        wx.ready(function() {
            // wx.checkJsApi({
            //     jsApiList : ['scanQRCode'],
            //     success : function(res) {
            //         alert("检验:" + res.errMsg);
            //     }
            // });
    
            //扫描二维码
            document.querySelector('#scanQRCode').onclick = function() {
                wx.scanQRCode({
                    needResult : 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
                    scanType : [ "qrCode", "barCode" ], // 可以指定扫二维码还是一维码,默认二者都有
                    success : function(res) {
                        var result = res.resultStr; // 当needResult 为 1 时,扫码返回的结果
                        document.getElementById("wm_id").value = result;//将扫描的结果赋予到jsp对应值上
                        if(result.length > 0)
                        {
                            var QRCodeStr = result.split(",")
                            //alert('<?php echo $base_url;?>/index/result?code='+QRCodeStr[1]);
                            window.location.href='<?php echo $base_url;?>/index/result?code='+QRCodeStr[1];
                        }else{
                            alert("扫描失败::扫描码=" + result);
                        }
    
                    }
                });
            };//end_document_scanQRCode
    
        });//end_ready
    </script>
    
    
    
    </body>
    </html>
    

      

    通过config接口注入权限验证配置

    这一步非常重要,也是最关键的一步,这一部分 
    先看官方的示例

    wx.config({
        debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
        appId: '', // 必填,公众号的唯一标识
        timestamp: , // 必填,生成签名的时间戳
        nonceStr: '', // 必填,生成签名的随机串
        signature: '',// 必填,签名,见附录1
        jsApiList: [] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
    });
    

      

    这里需要从服务器端网页面传递的参数有timestamp、nonceStr和signature而appId和jsApiList都是固定的,这里直接写在页面中。

    首先,编写服务器端代码,生成timestamp、nonceStr和signature。 
    在生成timestamp、nonceStr和signature的时候有两个参数需要获取 
    一个是access_token,另一个是jsapi_ticket。

    access_token的获取需要AppId和AppSecret,获取地址如下,发送GET请求

    https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
    

      

    通过HttpClient发送http请求就可以获取到access_token

    得到access_token之后,采用http GET方式请求获得jsapi_ticket

    https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
    

      

    注意,access_token和jsapi_ticket得有效期为7200秒,开发者必须在自己的服务全局缓存

    获得jsapi_ticket之后,就可以生成JS-SDK权限验证的签名了。

    我的获取ticket/jsapi , token的php代码

    用redis缓存,把token,jsapi_ticket存储起来

     /****************************js api 相关*********************************/
    
        public function getToken()
        {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL,
                "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . WxConfig::$APPID . "&secret=" . WxConfig::$APPSECRET);
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
            curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)');
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
            curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            $tmpInfo = curl_exec($ch);
            if (curl_errno($ch)) {
                //echo 'access_token  curl error' . PHP_EOL;
            }
            if(empty($tmpInfo)){
                //echo "no back";
            }
            $tmpInfo = json_decode($tmpInfo);
            if (isset($tmpInfo->errcode)) {
                // 获取token失败
                //echo 'access_token error' . PHP_EOL;
            } else {
                //echo 'access_token  ok' . PHP_EOL;
                $this->redis->setex(WxConfig::$APPID."_token", 7200, $tmpInfo->access_token);
            }
    
        }
    
    
        private function getJsapiTicket($access_token)
        {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL,
                "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=" . $access_token);
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
            curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)');
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
            curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            $tmpInfo = curl_exec($ch);
            if (curl_errno($ch)) {
                //echo 'js api ticket  curl error' . PHP_EOL;
            }
    
            $tmpInfo = json_decode($tmpInfo);
            if (isset($tmpInfo->errcode) && $tmpInfo->errcode != 0) {
                // 获取token失败
                //echo 'js api ticket  error' . PHP_EOL;
            } else {
                //echo 'js api ticket  ok' . PHP_EOL;
                $this->redis->setex(WxConfig::$APPID."_jsapi", 7200, $tmpInfo->ticket);
    
            }
        }
    
    
        /**
         * 获取指定长度的随机字符串
         * @param number $length
         * @return string
         */
        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;
        }
    
        /**
         * 获取js api config方法的签名
         * @return String
         */
        public function getSignPackage()
        {
            //jsapi
            $jsapitTicket = $this->redis->get(WxConfig::$APPID."_jsapi");
    
            $url = $this->config->baseUrl.'/';
            $timestamp = time();
            $nonceStr = $this->createNonceStr();
    
            // 这里参数的顺序要按照 key 值 ASCII 码升序排序
            $string = "jsapi_ticket=$jsapitTicket&noncestr=$nonceStr&timestamp=$timestamp&url=$url";
    
            $signature = sha1($string);
    
            $signpackage = array(
                "appId"     => WxConfig::$APPID,
                "nonceStr"  => $nonceStr,
                "timestamp" => $timestamp,
                "url"       => $url,
                "signature" => $signature,
                "rawString" => $string
            );
            return $signpackage;
        }
        /****************************js api 相关*********************************/
    

      

    然后自动判断token/jsapi_ticket是否过期:

    $access_token = $this->redis->get(WxConfig::$APPID."_token");
            if(empty($access_token))
            {
                //已过期
                $access_token = '';
                $this->getToken();
                $access_token = $this->redis->get(WxConfig::$APPID."_token");
                $this->getJsapiTicket($access_token);
    
            }else if(!empty($access_token))
            {
                $this->getJsapiTicket($access_token);
            }
    

      

  • 相关阅读:
    css3中-webkit-text-size-adjust详解
    CSS 让标点符号不出现在行首
    html.day02
    老生常谈的问题——抽象类与接口
    C# 4个小技巧
    IIS状态代码的含义
    关于线程的synchronized、wait(),notify
    再说粗粒度
    粗粒度与细粒度
    .NET中栈和堆的比较 #1
  • 原文地址:https://www.cnblogs.com/achengmu/p/9190994.html
Copyright © 2011-2022 走看看