简介
微信JS-SDK是微信公众平台 面向网页开发者提供的基于微信内的网页开发工具包。
通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用微信分享、扫一扫、卡券、支付等微信特有的能力,为微信用户提供更优质的网页体验。
此文档面向网页开发者介绍微信JS-SDK如何使用及相关注意事项。
JSSDK使用步骤
步骤一:绑定域名
步骤二:引入JS文件
<!doctype html>
<html>
<head>
<!--<meta charset="utf-8">-->
<title>{{headTitle}}</title>
<base href="/">
<meta content="text/html; charset=utf-8" http-equiv="Content-Type"/>
<meta content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">
<meta content="application/xhtml+xml;charset=UTF-8" http-equiv="Content-Type">
<meta content="no-cache,must-revalidate" http-equiv="Cache-Control">
<meta content="no-cache" http-equiv="pragma">
<meta content="0" http-equiv="expires">
<meta content="telephone=no, address=no" name="format-detection">
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/>
<script src="/sc-srv/js/utils/url.js"></script>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<script src="https://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
</head>
<body>
<div ng-view></div>
<loading></loading>
<script data-main="/sc-srv/js/main" src="/sc-srv/js/libs/require.js"></script>
</body>
</html>
步骤三:通过config接口注入权限验证配置
client端js配置
//======================
return app
.run(function($http,$window,$location,httpService){
$http({
method: "POST",
url: "/sc-srv/wechatjssdk/getjssdkconfig",
headers: { 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8' },
data: {url: $location.$$absUrl},
}).success(function(data, status) {
console.log(data);
$window.wx.config(
{
appId: data.data.appId,
nonceStr: data.data.nonceStr,
signature: data.data.signature,
timestamp: parseInt(data.data.timestamp),
jsApiList: [
'checkJsApi',
'onMenuShareAppMessage',
'onMenuShareTimeline',
'hideMenuItems'
]
}
);
}).
error(function(data, status) {
alerToast('连接服务器出错!',2000);
});
}) .controller('indexCtrl', ['$window','$scope','$rootScope','$http','$location','userService', function ($window,$scope,$rootScope,$http,$location,userService) {
$window.wx.ready(
function(){
var link='这是链接地址';
var desc='这是描述信息';
var imgUrl='这是图片地址';
$window.wx.checkJsApi({
jsApiList: [
'onMenuShareAppMessage',
'onMenuShareTimeline'
],
success: function (res) {
// alert(JSON.stringify(res),2000);
}
});
//隐藏菜单
$window.wx.hideMenuItems({
menuList: [
'menuItem:share:qq',
'menuItem:share:weiboApp',
'menuItem:share:facebook',
'menuItem:share:QZone',
'menuItem:openWithSafari',
'menuItem:readMode',
'menuItem:copyUrl',
'menuItem:share:email'
]
});
$window.wx.onMenuShareTimeline({
title: '蓝海金融', // 分享标题
desc: desc,
link: link, // 分享链接
imgUrl:imgUrl, // 分享图标
success: function () {
// 用户确认分享后执行的回调函数
alerToast('已分享',2000);
},
cancel: function () {
// 用户取消分享后执行的回调函数
alerToast('已取消',2000);
}
});
$window.wx.onMenuShareAppMessage({
title: '蓝海金融',
desc: desc,
link: link,
imgUrl: imgUrl,
success: function (res) {
// 用户确认分享后执行的回调函数
alerToast('已分享',2000);
},
cancel: function (res) {
// 用户取消分享后执行的回调函数
alerToast('已取消',2000);
}
});
}
);
//===================================
server端获取JSSDK配置信息
/**
* @Title: getJSSDKConfig
* @Description: TODO 加载配置
* @param url
* @return
* @return Message<Map<String,String>> 返回类型
* @throws
*/
public Message<Map<String,String>> getJSSDKConfig(String url){
int code=1002;
String msg="获取成功!";
Map<String,String> data=new HashMap<>();
try {
if(StringUtils.isEmpty(url)){
code=-1019;
msg="缺少必要参数";
}else{
WxJsapiConfig wxJsapiConfig=new WxService().createJsapiConfig(url, null);
data.put("appId", WxConfig.getInstance().getAppId());
data.put("nonceStr", wxJsapiConfig.getNoncestr());
data.put("signature", wxJsapiConfig.getSignature());
data.put("timestamp", wxJsapiConfig.getTimestamp()+"");
}
} catch (Exception e) {
e.printStackTrace();
code=-6666;
msg="服务器开小差啦!";
}
return MessageUtil.getMessage(data, code, msg, null);
}
public WxJsapiConfig createJsapiConfig(String url, List<String> jsApiList) throws WxErrorException {
long timestamp = System.currentTimeMillis() / 1000;
String noncestr = RandomUtils.getRandomStr(16);
String jsapiTicket = getJsapiTicket();
try {
String signature = SHA1.genWithAmple("noncestr="+noncestr,
"jsapi_ticket="+jsapiTicket,"timestamp="+timestamp,"url="+url);
WxJsapiConfig jsapiConfig = new WxJsapiConfig();
jsapiConfig.setTimestamp(timestamp);
jsapiConfig.setNoncestr(noncestr);
jsapiConfig.setUrl(url);
jsapiConfig.setSignature(signature);
jsapiConfig.setJsApiList(jsApiList);
return jsapiConfig;
} catch (NoSuchAlgorithmException e) {
throw new WxErrorException("[wx-tools]createJsapiConfig failure.");
}
}
public String getJsapiTicket() throws WxErrorException {
String url = WxConsts.URL_GET_JS_API_TICKET.replace("ACCESS_TOKEN", getAccessToken());
String responseContent = execute(new SimpleGetRequestExecutor(), url, null);
ObjectMapper mapper = new ObjectMapper();
JsonNode node = null;
try {
node = mapper.readTree(responseContent);
if(node.get("errcode")!=null && !(node.get("errcode").asInt()==0)){
WxError error = WxError.fromJson(responseContent);
throw new WxErrorException(error);
}
return jsapiTicket = node.get("ticket").asText();
} catch (Exception e) {
throw new WxErrorException("[wx-tools]getJsapiTicket failure.");
}
return null;
}
接口地址: public static final String URL_GET_JS_API_TICKET = “https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi“;
SHA1.java
package com.bigbigbu.wx.tools.util.crypto;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import org.apache.commons.codec.digest.DigestUtils;
import com.bigbigbu.wx.tools.exception.AesException;
/**
* SHA1
* @author
*/
public class SHA1 {
/**
* 串接arr参数,生成sha1 digest
*
* @param arr
* @return
*/
public static String gen(String token, String timestamp,String nonce) throws NoSuchAlgorithmException {
String[] arr = new String[] { token, timestamp, nonce };
Arrays.sort(arr);
StringBuffer content = new StringBuffer();
for (String a : arr) {
content.append(a);
}
return DigestUtils.shaHex(content.toString());
}
/**
* 用&串接arr参数,生成sha1 digest
*
* @param arr
* @return
*/
public static String genWithAmple(String... arr) throws NoSuchAlgorithmException {
Arrays.sort(arr);
StringBuffer sb = new StringBuffer();
for (int i = 0; i < arr.length; i++) {
String a = arr[i];
sb.append(a+"&");
}
String string1 = sb.toString().substring(0, sb.length()-1);
return DigestUtils.shaHex(string1);
}
/**
* 用SHA1算法生成安全签名
* @param token 票据
* @param timestamp 时间戳
* @param nonce 随机字符串
* @param encrypt 密文
* @return 安全签名
* @throws AesException
*/
public static String getSHA1(String token, String timestamp, String nonce, String encrypt) throws AesException
{
try {
String[] array = new String[] { token, timestamp, nonce, encrypt };
StringBuffer sb = new StringBuffer();
// 字符串排序
Arrays.sort(array);
for (int i = 0; i < 4; i++) {
sb.append(array[i]);
}
String str = sb.toString();
// SHA1签名生成
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(str.getBytes());
byte[] digest = md.digest();
StringBuffer hexstr = new StringBuffer();
String shaHex = "";
for (int i = 0; i < digest.length; i++) {
shaHex = Integer.toHexString(digest[i] & 0xFF);
if (shaHex.length() < 2) {
hexstr.append(0);
}
hexstr.append(shaHex);
}
return hexstr.toString();
} catch (Exception e) {
e.printStackTrace();
throw new AesException(AesException.ComputeSignatureError);
}
}
}
WxJsapiConfig.java
package com.bigbigbu.wx.tools.bean;
import java.io.IOException;
import java.util.List;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
/**
* Jsapi signature
*
* @author antgan
*
*/
public class WxJsapiConfig {
private String appid;
private String noncestr;
private long timestamp;
private String url;
private String signature;
private List<String> jsApiList;
public List<String> getJsApiList() {
return jsApiList;
}
public void setJsApiList(List<String> jsApiList) {
this.jsApiList = jsApiList;
}
public String getSignature() {
return signature;
}
public void setSignature(String signature) {
this.signature = signature;
}
public String getNoncestr() {
return noncestr;
}
public void setNoncestr(String noncestr) {
this.noncestr = noncestr;
}
public long getTimestamp() {
return timestamp;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getAppid() {
return appid;
}
public void setAppid(String appid) {
this.appid = appid;
}
public String toJson() throws JsonGenerationException, JsonMappingException, IOException{
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(this);
}
}