公司产品集成了airkiss库,因此需要在公众号里做个适配。
一:绑定域名
先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。
二:引入JS文件
在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.0.0.js
三:通过config接口注入权限验证配置
wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '', // 必填,公众号的唯一标识
timestamp: , // 必填,生成签名的时间戳
nonceStr: '', // 必填,生成签名的随机串
signature: '',// 必填,签名
jsApiList: [] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});
四:通过ready接口处理成功验证
wx.ready(function(){
// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
});
五:通过error接口处理失败验证
wx.error(function(res){
// config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
});
六:签名
微信JS接口都需要验证签名,因此需要先获取access_token,通过access_token再来获取jsapi_ticket,再利用jsapi_ticket和link url拼接成待校验字符串,然后通过sha1算法得出校验码。
class Sign {
public static void main(String[] args) {
String jsapi_ticket = "jsapi_ticket";
// 注意 URL 一定要动态获取,不能 hardcode
String url = "http://example.com";
Map<String, String> ret = sign(jsapi_ticket, url);
for (Map.Entry entry : ret.entrySet()) {
System.out.println(entry.getKey() + ", " + entry.getValue());
}
};
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;
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);
}
}
七:实践
把上面签名得出的校验码,随机字符串,时间戳,填入wx.config,再填入公众号的id,授权就完成了,最终html如下:
```
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href=".">
<meta charset="UTF-8">
<title>DEMO-WIFI配网</title>
<!-- 最高ie版本渲染 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- 响应布局 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<!-- 不自动解析为手机号码 -->
<meta name="format-detection" content="telephone=no">
<!-- 默认webkit渲染 -->
<meta name="renderer" content="webkit">
<!-- 不百度转码 -->
<meta http-equiv="Cache-Control" content="no-siteapp">
<!-- Amaze UI h5跨屏前段框架 -->
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<link rel="stylesheet" href="css/amazeui.min.css"/>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
html, body {
height: 100%;
width: 100%;
}
#next {
width: 100%;
height: 45;
font-size: 16;
color: white;
border-width: inherit;
border-radius: 10px;
background-color: lightseagreen;
}
div.main{
text-align:center;
width:70%;
margin-left: auto;
margin-right: auto;
}
</style>
<script>
</script>
</head>
<body>
<div class="main">
<img id="logo" style="z-index:-1;width:100%;max-height:20%;" src="img/logo.png" />
<br>
<div style="font-size:30;color: #1890e9;">DEMO</div>
<div style="font-size:25;color: #1890e9;">DEMO_DESC</div>
<br><br><br><br><br><br>
<div style="font-size:16;color: darkgray;">请按设备上的配网键,听到“进入网络配置模式”提示后,点击“下一步”</div>
<br>
<button id="next" type="button" class="am-btn" style="background: #1890e9;">下一步</button>
</div>
<br><br>
<div id="message"></div>
<!--[if (gte IE 9)|!(IE)]><!-->
<script src="js/jquery.min.js"></script>
<!--<![endif]-->
<script src="js/jweixin-1.0.0.js"></script>
<script type="text/javascript">
//$(function(){
//$('#next').on('touchstart',function(e){
// $(this).css('backgroundColor','green');
// e.preventDefault();
//}).on('touchend',function(e){
// $(this).css('backgroundColor','lightseagreen');
//});
//});
wx.config({
beta : true, // 开启内测接口调用,注入wx.invoke方法
debug : false, // 开启调试模式
appId : 'wxd0f8344add82531e', // 第三方app唯一标识
timestamp : '1480666491', // 生成签名的时间戳
nonceStr : 'cc16cd3c-299a-4244-aaac-5e166a73312e', // 生成签名的随机串
signature : '1F2214B0B2B46DBCA52D318D14D1F70F42E68EBA',// 签名
jsApiList : ['configWXDeviceWiFi','hideOptionMenu'] // 需要使用的jsapi列表
});
var second = 5;
wx.ready(function () {
wx.checkJsApi({
jsApiList: ['configWXDeviceWiFi','hideOptionMenu'],
success: function(res) {
// 关闭右上角菜单
wx.hideOptionMenu();
$("#next").click(function(){
wx.invoke('configWXDeviceWiFi', {}, function(res){
var err_msg = res.err_msg;
if(err_msg == 'configWXDeviceWiFi:ok') {
alert("网络配置成功");
return;
}else if(err_msg == 'configWXDeviceWiFi:cancel') {
alert("您已取消网络配置");
return;
} else {
alert("网络配置失败");
}
});
});
}
});
});
</script>
</body></html>
```