绑定JS接口域名

  • 先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。

  • 备注:登录后可在“开发者中心”查看对应的接口权限。

在html页面引入JS文件

  • 一般引入如下

    1
    <script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
  • 当上述资源不可访问时,可改访问

    1
    <script type="text/javascript" src="http://res2.wx.qq.com/open/js/jweixin-1.6.0.js"></script>

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

  • 在调用接口的页面写入js代码

    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
    //项目的url,从后台controller传入
    var BASE_PATH = '[(${basepath})]';
    //需要把当前页面的url地址传到后台,生成签名信息时需要使用到
    var tokenUrl= window.location.href;
    //获取签名的后台接口
    var getWechatSignUrl = BASE_PATH+'/main/getsignaturedata';

    //获取微信接口的
    $.ajax({
    url:getWechatSignUrl,
    //请求方式
    type : "POST",
    dataType : "json",
    data:{tokenUrl:tokenUrl},
    success : function(data) {
    //获得签名之后传入配置中进行配置
    wx.config({
    // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
    debug: false,
    // 必填,企业号的唯一标识,此处填写企业号corpid
    appId: 'wxe6774713a448fb6f',
    // 必填,生成签名的时间戳
    timestamp: data.timestamp,
    // 必填,生成签名的随机字符串
    nonceStr: 'Wm3WZYTPz0wzccnW',
    // 必填,签名,见附录1
    signature: data.signature,
    // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
    jsApiList: ['getLocation','scanQRCode','chooseImage','uploadImage']
    });
    }
    });
  • 获取签名的后台地址

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     	//登记页面需要的微信签名
    @RequestMapping("getsignaturedata")
    @ResponseBody
    public JSONObject getsignaturedata(HttpServletRequest request, String tokenUrl) {
    // 为获取jsapi_ticket而获取access_token
    String access_token = jsapi_ticketUtil.getticketaccesstoken();
    // 获得jsapi_ticket
    String jsapi_ticket = jsapi_ticketUtil.getjsapi_ticket(access_token);
    // 生成签名的时间戳
    String timestamp = Long.toString(jsapi_ticketUtil.timestamp);
    // 获取签名signature
    String signature = jsapi_ticketUtil.getsignature(jsapi_ticket, tokenUrl);
    //页面需要的参数
    JSONObject resultObject = new JSONObject();
    resultObject.put("signature", signature);
    resultObject.put("timestamp", Long.parseLong(timestamp));
    return resultObject;
    }
  • 生成jsapi_ticket的工具类jsapi_ticketUtil

    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
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    import java.io.IOException;
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;

    import org.apache.http.HttpStatus;
    import org.apache.http.client.methods.CloseableHttpResponse;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.util.EntityUtils;

    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.JSONObject;

    public class jsapi_ticketUtil {
    //微信公众号的APPID和secret
    public static String appid = "wxe6774713a448fb6f";
    public static String secret = "1fec63da4f2a53c3224e6adf6dd4876e";
    public static String access_token = "";
    public static Long timestamp = null;

    //为获取jsapi_ticket而获取access_token
    public static String getticketaccesstoken() {
    //System.out.println("access_token:"+access_token);
    //System.out.println("timestamp:"+timestamp);
    if(access_token == "") {
    String url = "https://api.weixin.qq.com/cgi-bin/token?";
    String params = "appid="+appid+"&secret="+secret+"&grant_type=client_credential";
    //调用httpGet方法发送url并返回json对象,可以获取access_token
    JSONObject jsonObject = httpGet(url+params);
    access_token = jsonObject.getString("access_token");
    //System.out.println("access_token=" + access_token);
    timestamp = System.currentTimeMillis()/1000;
    return access_token;
    }else {
    long timestamp2 = System.currentTimeMillis()/1000;
    long resultchatime = timestamp2-timestamp;
    if(resultchatime > 7000) {
    String url = "https://api.weixin.qq.com/cgi-bin/token?";
    String params = "appid="+appid+"&secret="+secret+"&grant_type=client_credential";
    //调用httpGet方法发送url并返回json对象,可以获取access_token
    JSONObject jsonObject = httpGet(url+params);
    access_token = jsonObject.getString("access_token");
    //System.out.println("access_token=" + access_token);
    timestamp = System.currentTimeMillis()/1000;
    return access_token;
    }
    return access_token;
    }
    }

    //获取jsapi_ticket
    public static String getjsapi_ticket(String access_token) {
    String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?";
    String params = "access_token="+access_token+"&type=jsapi";
    JSONObject jsonObject = httpGet(url+params);
    //System.out.println("jsonObject1=" + jsonObject.toString());
    String jsapi_ticket = jsonObject.getString("ticket");
    //System.out.println("jsapi_ticket=" + jsapi_ticket);
    return jsapi_ticket;
    }

    //获取signature
    public static String getsignature(String jsapi_ticket,String tokenUrl) {
    //生成签名的随机数
    String noncestr = "Wm3WZYTPz0wzccnW";
    //生成签名的集合字符串
    //tokenUrl(当前网页的URL)
    String str = "jsapi_ticket=" + jsapi_ticket +
    "&noncestr=" + noncestr +
    "&timestamp=" + Long.toString(timestamp) +
    "&url=" + tokenUrl;
    //sha1加密
    String signature = SHA1(str);
    //System.out.println("signature=" + signature);
    return signature;
    }

    // 使用htpClient发送url请求获取返回,用阿里的fastjson解析json
    public static JSONObject httpGet(String url) {
    JSONObject jsonResult = null;
    try {
    //目前HttpClient最新版的实现类为CloseableHttpClient
    CloseableHttpClient client = HttpClients.createDefault();
    HttpGet request = new HttpGet(url);
    //执行Request请求,CloseableHttpClient的execute方法返回的response都是CloseableHttpResponse类型
    CloseableHttpResponse response = client.execute(request);
    //判断响应的状态码是否为200
    if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
    //用EntityUtils.toString()这个静态方法将HttpEntity转换成字符串,防止服务器返回的数据带有中文,所以在转换的时候将字符集指定成utf-8就可以了
    String strResult = EntityUtils.toString(response.getEntity(),"UTF-8");
    //将字符串转换json对象
    jsonResult = JSON.parseObject(strResult);
    } else {
    System.out.println("请求出错");
    }
    } catch (IOException e) {
    e.printStackTrace();
    }
    return jsonResult;
    }

    //SHA-1算法加密
    public static String SHA1(String str) {
    try {
    MessageDigest digest = java.security.MessageDigest.getInstance("SHA-1"); //如果是SHA加密只需要将"SHA-1"改成"SHA"即可
    digest.update(str.getBytes());
    byte messageDigest[] = digest.digest();
    // Create Hex String
    StringBuffer hexStr = new StringBuffer();
    // 字节数组转换为 十六进制 数
    for (int i = 0; i < messageDigest.length; i++) {
    String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
    if (shaHex.length() < 2) {
    hexStr.append(0);
    }
    hexStr.append(shaHex);
    }
    return hexStr.toString();

    } catch (NoSuchAlgorithmException e) {
    e.printStackTrace();
    }
    return null;
    }
    }

通过ready接口处理成功验证

1
2
3
   wx.ready(function(){
// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
});

通过error接口处理失败验证

1
2
3
   wx.error(function(res){
// config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
});

接口调用说明

  • 所有接口通过wx对象(也可使用jWeixin对象)来调用,参数是一个对象,除了每个接口本身需要传的参数之外,还有以下通用参数

    1
    2
    3
    4
    5
    success:接口调用成功时执行的回调函数。
    fail:接口调用失败时执行的回调函数。
    complete:接口调用完成时执行的回调函数,无论成功或失败都会执行。
    cancel:用户点击取消时的回调函数,仅部分有用户取消操作的api才会用到。
    trigger: 监听Menu中的按钮点击时触发的方法,该方法仅支持Menu中的相关接口。

备注:不要尝试在trigger中使用ajax异步请求修改本次分享的内容,因为客户端分享操作是一个同步操作,这时候使用ajax的回包会还没有返回。

  • 以上几个函数都带有一个参数,类型为对象,其中除了每个接口本身返回的数据之外,还有一个通用属性errMsg,其值格式如下

    1
    2
    3
    4
    5
    调用成功时:"xxx:ok" ,其中xxx为调用的接口名
    用户取消时:"xxx:cancel",其中xxx为调用的接口名
    调用失败时:其值为具体错误信息

    如:{latitude: 31.95266, longitude: 118.84002, errMsg: "getLocation:ok"}