示例是在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;
}
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 +
"×tamp=" + 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