H5实现 js-sdk 微信扫一扫
H5实现 js-sdk 微信扫一扫
配置和绑定域名
先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。
微信公众平台
https://mp.weixin.qq.com/
手机扫码登录
如图所示,进行配置(将第四步文件下载,上传到指定位置),如:
1、springboot
项目,放在项目中resources
文件夹下,保证 域名+项目名+该文件名
能访问到
域名填写为 域名+项目名
2、直接放在服务器的目录中,可通过nginx
转发达到可以访问即可
域名填写为域名
备注:登录后可在“开发者中心”查看对应的接口权限。
引入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)。
加入如下资源即可
<link rel="stylesheet" href="https://res.wx.qq.com/open/libs/weui/2.0.0/weui.min.css">
<script src="http://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>
<script src="https://res.wx.qq.com/open/libs/weuijs/1.1.4/weui.min.js"></script>
备注:支持使用 AMD/CMD 标准模块加载方法加载
前端代码
var jsApiList = [
'checkJsApi',
'scanQRCode'
];
function init() {
// console.log("url = " + location.href.split("#")[0])
//获取签名
$.ajax({
url:"你的后台地址",
method:"post",
data:{url:location.href.split("#")[0]},
dataType: "json",
success:function (data) {
console.info("data = " , data);
var appId = data['appId'];
var timestamp = data['timestamp'];
var nonceStr = data['nonceStr'];
var signature = data['signature'];
//1 通过config接口注入权限验证配置
wx.config({
debug: false, /// // true是开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: appId,
timestamp: timestamp,
nonceStr: nonceStr,
signature: signature,
jsApiList: jsApiList
});
//2 通过ready接口处理成功验证
wx.ready(function () {
//check client vserion wether support JS API
wx.checkJsApi({
jsApiList: ['scanQRCode'],
success: function (res) {
// weui.alert(res.errMsg);
wx.scanQRCode({
needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
scanType: ["qrCode", "barCode"], // 可以指定扫二维码还是一维码,默认二者都有
success: function (res) {
console.log(res)
}
});
}
});
});
//3 通过error接口处理失败验证
//wrong error msg
wx.error(function (res) {
weui.alert("出错了请稍后再试!" + res.errMsg);
});
},
error:function (data) {
weui.alert("网络异常,请稍后再试。");
}
});
}
//scanning Qr code
function scanQRCodeFun() {
// 初始化,成功后,会调用微信扫一扫
init();
};
后端代码
获取 Access token
仅是示例,可根据自己情况修改
WX_APPID
和WX_APPSECRET
替换成自己的
public String getWxAccessToken() throws IOException {
String getUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+WX_APPID+"&secret="+WX_APPSECRET;
String res = "";
// 创建一个URL对象
URL url = new URL(getUrl);
// 打开一个连接
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// 设置请求方式为GET
connection.setRequestMethod("GET");
// 设置连接超时时间
connection.setConnectTimeout(5000);
// 设置读取超时时间
connection.setReadTimeout(5000);
// 发送请求
connection.connect();
// 获取响应码
int responseCode = connection.getResponseCode();
if (responseCode == 200) {
// 获取响应内容
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuffer sb = new StringBuffer();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
reader.close();
// 解析响应内容
System.out.println(sb.toString());
res = sb.toString();
} else {
System.out.println("响应码:" + responseCode);
}
// 关闭连接
connection.disconnect();
return res;
}
获取 jsapi_ticket
生成签名之前必须先了解一下jsapi_ticket,jsapi_ticket是公众号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket 。
- 参考以下文档获取access_token(有效期7200秒,开发者必须在自己的服务全局缓存access_token):https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html
- 用第一步拿到的access_token 采用http GET方式请求获得jsapi_ticket(有效期7200秒,开发者必须在自己的服务全局缓存jsapi_ticket):https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
成功返回如下JSON:
{
"errcode":0,
"errmsg":"ok",
"ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA",
"expires_in":7200
}
获得jsapi_ticket之后,就可以生成JS-SDK权限验证的签名了。
仅是示例,可根据自己情况修改
wxAccessToken
就是上面获取到的
public String getWxJsapiTicket(String wxAccessToken) throws IOException {
String getUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+wxAccessToken+"&type=jsapi";
String res = "";
// 创建一个URL对象
URL url = new URL(getUrl);
// 打开一个连接
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// 设置请求方式为GET
connection.setRequestMethod("GET");
// 设置连接超时时间
connection.setConnectTimeout(5000);
// 设置读取超时时间
connection.setReadTimeout(5000);
// 发送请求
connection.connect();
// 获取响应码
int responseCode = connection.getResponseCode();
if (responseCode == 200) {
// 获取响应内容
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuffer sb = new StringBuffer();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
reader.close();
// 解析响应内容
System.out.println(sb.toString());
res = sb.toString();
} else {
System.out.println("响应码:" + responseCode);
}
// 关闭连接
connection.disconnect();
return res;
}
权限签名
WX_APPID
替换成自己的
// 签名用的url必须是调用JS接口页面的完整URL
public 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("appId",WX_APPID);
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);
}
然后在控制层将结果返回到前端
注意
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!