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

来源:互联网 发布:学生就业压力大数据 编辑:程序博客网 时间:2024/05/22 15:53

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

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

步骤一:绑定域名

绑定域名 

    如果域名绑定有误,会出现如下错误提示 
    错误的域名配置示例:

`http://gwchsk.imwork.net/wechat/order/test.html`

    域名配置错误的提示信息: 
{“errMsg”:”config:invalid url domain”}

这里写图片描述

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

这里写图片描述

步骤二:引入JS文件

    一行代码就可以了

<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
  • 1

步骤三:通过config接口注入权限验证配置

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

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

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

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

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

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

    通过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
  • 1

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

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

签名算法

签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。

签名算法的实现

    最难的就是签名算法的实现部分,幸好微信给了demo,网上好多人都在找,这里我把签名算法的实现贴出来,代码来自微信demo 
这里写图片描述 
    下载地址 
    java代码如下,做了一点点修改

package com.gwc.wechat.utils.wechat;import java.io.UnsupportedEncodingException;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.util.Formatter;import java.util.HashMap;import java.util.Map;import java.util.UUID;public class WxJSUtil {    public static void main(String[] args) {        // 注意 URL 一定要动态获取,不能 hardcode        String url = "http://gwchsk.imwork.net/wechat/order/test.html";        Map<String, String> ret = sign(url);        for (Map.Entry entry : ret.entrySet()) {            System.out.println(entry.getKey() + "=" + entry.getValue());        }    };    public static Map<String, String> sign(String url) {        Map<String, String> ret = new HashMap<String, String>();        //这里的jsapi_ticket是获取的jsapi_ticket。        String jsapi_ticket = JSAPITicketTool.getTicket();        String nonce_str = create_nonce_str();        String timestamp = create_timestamp();        String string1;        String signature = "";        //注意这里参数名必须全部小写,且必须有序        string1 = "jsapi_ticket=" + jsapi_ticket +                  "&noncestr=" + nonce_str +                  "&timestamp=" + timestamp +                  "&url=" + url;       // System.out.println(string1);        try        {            MessageDigest crypt = MessageDigest.getInstance("SHA-1");            crypt.reset();            crypt.update(string1.getBytes("UTF-8"));            signature = byteToHex(crypt.digest());        }        catch (NoSuchAlgorithmException e)        {            e.printStackTrace();        }        catch (UnsupportedEncodingException e)        {            e.printStackTrace();        }        ret.put("url", url);        ret.put("jsapi_ticket", jsapi_ticket);        ret.put("nonceStr", nonce_str);        ret.put("timestamp", timestamp);        ret.put("signature", signature);        return ret;    }    private static String byteToHex(final byte[] hash) {        Formatter formatter = new Formatter();        for (byte b : hash)        {            formatter.format("%02x", b);        }        String result = formatter.toString();        formatter.close();        return result;    }    private static String create_nonce_str() {        return UUID.randomUUID().toString();    }    private static String create_timestamp() {        return Long.toString(System.currentTimeMillis() / 1000);    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82

    Controller的代码

@Controller@RequestMapping(value = "/order")public class OrderController {@RequestMapping(value = "/test.html", method = RequestMethod.GET)    public String testPage(Model model) {        String url = Constant.AppURL + "/order/test.html";        Map<String, String> ret = WxJSUtil.sign(url);         for (Map.Entry entry : ret.entrySet()) {                System.out.println(entry.getKey() + "=" + entry.getValue());                model.addAttribute(entry.getKey().toString(), entry.getValue());            }        return "jqueryMobile";    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

    在Controller中将如下参数写进了jsp页面

    timestamp=1449132293    nonceStr=fb4eaa58-6d53-40a8-a8fa-7033e9768a8a    signature=7ad32da3f82cb36492de935a60727d3053d33f4b
  • 1
  • 2
  • 3

    其次编写jsp页面的代码 
    在jsp页面中需要将wx.config重的参数进行配置

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

    在页面中读值

    <input id="timestamp" type="hidden" value="${timestamp}" />    <input id="noncestr" type="hidden" value="${nonceStr}" />    <input id="signature" type="hidden" value="${signature}" />
  • 1
  • 2
  • 3

    然后赋值

    <script type="text/javascript">        $(function() {            var timestamp = $("#timestamp").val();//时间戳            var nonceStr = $("#noncestr").val();//随机串            var signature = $("#signature").val();//签名            wx.config({                debug : true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。                appId : 'wx622ca8545e5c354b', // 必填,公众号的唯一标识                timestamp : timestamp, // 必填,生成签名的时间戳                nonceStr : nonceStr, // 必填,生成签名的随机串                signature : signature,// 必填,签名,见附录1                jsApiList : [ 'scanQRCode' ]            // 必填,需要使用的JS接口列表,所有JS接口列表见附录2            });        });    </script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

    写一个按钮和输入框,将扫描的结果放进输入框

<input id="id_securityCode_input"><button id="scanQRCode">扫码</button>
  • 1
  • 2

    给按钮绑定事件,并执行微信扫码

$("#scanQRCode").click(function() {            wx.scanQRCode({                // 默认为0,扫描结果由微信处理,1则直接返回扫描结果                needResult : 1,                desc : 'scanQRCode desc',                success : function(res) {                    //扫码后获取结果参数赋值给Input                    var url = res.resultStr;                    //商品条形码,取","后面的                    if(url.indexOf(",")>=0){                        var tempArray = url.split(',');                        var tempNum = tempArray[1];                        $("#id_securityCode_input").val(tempNum);                    }else{                        $("#id_securityCode_input").val(url);                    }                }            });        });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

    运行结果如图 
    扫一包抽纸

抽纸

扫描结果

放进input

    扫网址

这里写图片描述

这里写图片描述

    微信JS-SDK中的扫一扫就基本实现了。

0 0