JS调起微信扫一扫接口

示例是在JS调起微信扫一扫,扫描二维码并获取扫描结果!

1.首先是微信公众号绑定JS接口安全域名 , 直接放文档链接。 (文档步骤一)

https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#2

2.H5获取JSP 引入JS文件 (文档步骤二)

在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.6.0.js
如需进一步提升服务稳定性,当上述资源不可访问时,可改访问:http://res2.wx.qq.com/open/js/jweixin-1.6.0.js (支持https)。

3.通过config接口注入权限验证配置 (文档步骤三)

因为文档有详细说明,只讲一下遇到的问题。
我当时是在,页面点击按钮的时候进行配置,然后再调起扫一扫接口。然后config返回invalid signature签名错误。
当时这个问题找了很久,不管是配置信息还是签名,是没有问题的。最后解决办法是将config接口在JS 页面加载的时候
先进行配置,点击按钮的时候就直接调起扫一扫接口,就完美解决了。
wx.config接口就是微信的配置接口。
这里通过页面加载获取 配置的签名信息。后台代码放第4点。

$(function (){
	// 获取当前url
	var url = location.href.split('#')[0];
	var p = {m:"GETWECHATSCANINFO",url:url};
	var res = ajaxAssistant("wechat.action",p);
	if(res.code == 1000){
		res = $.parseJSON(res.msg);
		wxCfg(res.appId,res.timestamp,res.nonceStr,res.signature);
	}
	return false;
});
//配置wx js
function wxCfg(_appid,_timestamp, _nonceStr, _signature) {
	wx.config({
		debug :false,// 调试模式,调用的所有api的返回值会在客户端alert出来。true开启
		appId : _appid,// 必填,公众号的唯一标识,公众号后台唯一标识
		timestamp : _timestamp,// 必填,生成签名的时间戳 要与后台生成的签名一致。所以是传过来的
		nonceStr : _nonceStr,// 必填,生成签名的随机串 也跟后台生成的签名一致。
		signature : _signature,// 必填,签名
		jsApiList : ['checkJsApi', 'scanQRCode']// 必填,需要使用的JS接口列表,checkJsApi必填
	});
}

4.获取微信 api_ticket

api_ticket 是用于调用微信JS API的临时票据,有效期为7200 秒,通过access_token 来获取。
access_token就不想讲了,网上很多。
开发者注意事项:
1.此用于卡券接口签名的api_ticket与步骤三中通过config接口注入权限验证配置使用的jsapi_ticket不同。
2.由于获取api_ticket 的api 调用次数非常有限,频繁刷新api_ticket 会导致api调用受限,影响自身业务,开发者需在自己的服务存储与更新api_ticket。
接口调用请求说明
http请求方式: GET https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=wx_card

	public static String getTicket(String access_token){
		String jsapi_ticket = "";
		try {
			// token有效期    CacheUtil是封装起来的 Map集合
			Object time = CacheUtil.get(TICKET_TIME_KEY);
			boolean isReToken = false;
			if (null!=time) {
				// ticket 有效期 7200秒  120分钟  这里过了 100分钟获取一次 , 理论1小时可获取400次 但还是缓存起来
				boolean isE = isExpired(time.toString(), 100);
				isReToken = isE;
			} else {
				isReToken =!isReToken;
			}
			// true 重新获取
			if (isReToken) {
				String requestUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+access_token+"&type=jsapi";
				String response = HttpUtil.instanse().quickGetUrl(requestUrl, 10);
				JSONObject res = DataUtil.string2JSONObject(response);
				log.debug("#get_jsapi_ticket result is -> "+response);
				if(res.containsKey("ticket")){
					jsapi_ticket = res.getString("ticket");
					// 缓存时间戳  或 token 
					CacheUtil.set(TICKET_TOKEN_KEY,jsapi_ticket);
					CacheUtil.set(TICKET_TIME_KEY, System.currentTimeMillis());
				}
			} else {
				jsapi_ticket = CacheUtil.getString(TICKET_TOKEN_KEY);
			}
		} catch (Exception e) {
			log.debug("#request get_jsapi_ticket has error,",e);
		}
		return jsapi_ticket;
	}
	/**
	 * 验证时间戳
	 * @param tokenAging  时间戳
	 * @param m	验证超过的时间(分钟)
	 * @return true 超过 
	 */
	public static boolean isExpired (String tokenAging,int m) {
		boolean is = false;
		
		Date date = new Date(Long.parseLong(tokenAging));
		
        Long minute =(System.currentTimeMillis() - date.getTime()) / (1000 * 60); // 分钟为单位
        
        if (minute > m) {
        	is = true;
        }
        return is;
	}

5.根据api_ticket 进行签名签名 SHA-1 签名

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 static Map<String, String> sign(String jsapi_ticket, String url) {
        Map<String, String> ret = new HashMap<String, String>();
        // 字符串随机数
        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;
        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);
    }

6.最后可以调用微信扫一扫接口了

// 调起扫一扫  这里是点击扫一扫按钮的事件方法
function wxScan() {
	wx.ready(function() {//配置文件加载完成之后会自动调用ready中的模块
			wx.checkJsApi({
				jsApiList : ['scanQRCode'],
				success : function(res) {
					wx.scanQRCode({
						// 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
						needResult: 1,
						// 可以指定扫二维码还是一维码,默认二者都有
						scanType: ["qrCode","barCode"],
						success: function (res) {
							// result  这里直接返回二维码中的内容,根据内容可以做自己的业务了
							// needResult为1 时
		                    var val = res.resultStr;
		                    
						}
					});
				}
			});
		});
		wx.error(function(res) {
			alert("扫一扫调起失败:" + res.errMsg+",请重试!");
		});
}

7.常见错误

这里就直接放官方文档了,因为自己没遇到过。
https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#66

个人博客:unclepig.top

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章