一、公众号设置
1.账号详情:
公众号的头像、二维码、名称都是必须填写的,如果没有这些信息,是不能进行网页开发的。
2.功能设置
JS接口安全域名: 设置JS接口安全域名后,公众号开发者可在该域名下调用微信开放的JS接口。例如,在做分享的时候,需要引入微信的js文件,微信会对请求的域名校验是否合法。
网页授权域名: 授权回调页面域名。在做网页开发的时候,往往需要用户授权,在授权通过后,也会对域名进行合法性校验。
另:a.在JS接口安全域名和网页授权域名的设置中都需要下载一个认证证书,放到项目的根路径下,以便微信对访问的地址进行校验。
b.设置的域名为通过ICP备案的公网域名。
二、基本配置
1.公众号开发信息配置:
a.开发者ID:也就是公众号的id,用来标识当前的公众号。
b.开发者密码: 开发者密码是校验公众号开发者身份的密码,具有极高的安全性。一般在获取微信信息时需要此密码。
2.
服务器配置
主要功能: 启用并设置服务器配置后,用户发给公众号的消息以及开发者需要的事件推送,将被微信转发到该URL中。
在微信网页开发中,并没有涉及到这一部分内容,所以没有做过多的了解。
二、网页开发流程
对于微信公众号的二次开发是一个非常庞大的体系,而针对于公众号的网页开发仅仅是庞大体系中的非常小的一部分了。但是这一部分往往是最常用的一块内容,我本人也是因为项目需要才开始接触的。另一方面,由于自己认识的同事、朋友做这一部分开发的也特别少,所以自己只能摸着石头过河,跌跌撞撞的完成了领导交给的任务。在此贴出来,一是和大家分享一下自己的一点经验,希望对新接触这块内容的朋友有所帮助,二是希望自己能通过这次总结,能再有所收获。
1.对于微信公众号的开发,建议大家还是仔细读读微信给大家提供的
技术文档。虽然文档的内容总是感觉没有其他一些开发文档那样正式,但是介绍的还是挺全面的。比自己从网上找一些开发总结来的更加实惠,更加全面。
2.网页授权。
网页授权就是个人微信账号在打开公众号里的链接的时候需要个人微信账号运行公众号获取微信的信息。这是网页开发的重点,如果没有授权,那么就无法进行微信分享等其他操作。网页授权分为两种,一是静默授权,就是在微信用户在不知情的情况下就默认授权微信公众号获取微信用户的一部分信息,当然这部分信息是十分局限的,如微信账号在微信公众号里的openid等信息;二是用户授权,这种方式就是我们经常看到的那种,某某公众号需要获取您的以下信息,然后我们如果点击“确认登录”才会打开链接,否则就会打开失败。如下图:
3.获取微信公众号access_token和jspa_ticket
概念:
access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。
jsapi_ticket是公众号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket
说明:
由于access_token的有效时间仅仅两个小时,而且又是全局唯一接口调用凭据,所以在做网页开发的时候,首先要做的额就是获取access_token。但是对于此token信息,在微信服务端做了一个调用次数限制,即每个公众号每天最多可以调用2000次,所以为了保证系统时刻都能获取token信息,而且不超过获取次数,我们只能采取定时获取的方式。每天五分钟获取一次token信息(当然也可根据具体业务做出合适的调整)。
同理,jsapi_ticket同样需要定时获取。需要注意的是jsapi_ticket做js中生成签名的重要参数
获取方式:
a. access_token获取:
https请求方式: GET
返回结果:
{"access_token":"ACCESS_TOKEN","expires_in":7200}
b. jsapi_ticket获取:
用第一步拿到的access_token 采用http GET方式请求获得jsapi_ticket(有效期7200秒,开发者必须在自己的服务全局缓存jsapi_ticket):
返回结果:
{
"errcode":0,
"errmsg":"ok",
"ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA",
"expires_in":7200
}
4.获取code
对于code这个东西,在我刚开始接触微信网页开发的时候,一直想不明白,查了文档,还是不知道这个code是做什么的,是哪来的……
后来,时间长了,慢慢的才发现这个code仅仅是一个桥梁,它是在我们通过微信浏览器里访问我们的服务地址的时候,微信服务器会自动在目标地址的后边加上code等参数。所以我们如果用的是jsp页面,那么就通过request.getParameters("code")方法即可获取。假如用的是html页面,则需要将当前页面的url地址获取到,然后截取出code参数的值。当然这些操作的前提是通过微信的浏览器打开,否则是无效的。
获取方式:
注意:
APPID是公众号的id,REDIRECT_URI是我们目标服务的地址,SCOPE分为两种,主要是为了区分静默授权(
不弹出授权页面,直接跳转,只能获取用户openid)和显示授权(
弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,
即使在未关注的情况下,只要用户授权,也能获取其信息)
code说明 :
code作为换取access_token的票据,每次用户授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期。
5.获取openid
首先请注意,这里通过code换取的是一个特殊的网页授权access_token,与基础支持中的access_token(该access_token用于调用其他接口)不同。公众号可通过下述接口来获取网页授权access_token。如果网页授权的作用域为snsapi_base,则本步骤中获取到网页授权access_token的同时,也获取到了openid,snsapi_base式的网页授权流程即到此为止。
尤其注意:由于公众号的secret和获取到的access_token安全级别都非常高,必须只保存在服务器,不允许传给客户端。后续刷新access_token、通过access_token获取用户信息等步骤,也必须从服务器发起。
请求方法
获取code后,请求以下链接获取access_token:
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
返回结果:
{ "access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",
"scope":"SCOPE"
}
6.获取用户信息
如果网页授权作用域为snsapi_userinfo,则此时开发者可以通过access_token和openid拉取用户信息了。
请求方法
参数说明
参数
|
描述
|
access_token
|
网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
|
openid
|
用户的唯一标识
|
lang
|
返回国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语
|
返回说明:
{ "openid":" OPENID",
" nickname": NICKNAME,
"sex":"1",
"province":"PROVINCE"
"city":"CITY",
"country":"COUNTRY",
"headimgurl": "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ
4eMsv84eavHiaiceqxibJxCfHe/46",
"privilege":[ "PRIVILEGE1" "PRIVILEGE2" ],
"unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
}
参数
|
描述
|
openid
|
用户的唯一标识
|
nickname
|
用户昵称
|
sex
|
用户的性别,值为1时是男性,值为2时是女性,值为0时是未知
|
province
|
用户个人资料填写的省份
|
city
|
普通用户个人资料填写的城市
|
country
|
国家,如中国为CN
|
headimgurl
|
用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空。若用户更换头像,原有头像URL将失效。
|
privilege
|
用户特权信息,json 数组,如微信沃卡用户为(chinaunicom)
|
unionid
|
只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段。
|
7.分享功能
第一步:公众号配置。
公众号设置---》功能设置,设置JS接口安全域名和网页授权域名。
注:需要把认证证书下载到项目的根目录或者指定的目录文件下。
第二步:JS设置
在页面中引入微信对外js文件:
<script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
配置代码如下:
<script type="text/javascript">
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '${appid}', // 必填,公众号的唯一标识
timestamp : '${share.timestamp}', // 必填,生成签名的时间戳
nonceStr : '${share.noncestr}', // 必填,生成签名的随机串
signature : '${share.signature}',// 必填,签名,见附录1
jsApiList : ['onMenuShareTimeline','onMenuShareAppMessage','onMenuShareQQ','onMenuShareQZone'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});
wx.ready(function () {
wx.checkJsApi({
jsApiList: [
'getNetworkType',
'previewImage'
],
success: function (res) {
//alert(JSON.stringify(res));
}
});
var shareObj = {
title: '${shareTitle}',
desc: '分享描述',
link: '${shareQQUrl}',
imgUrl: '${shareImg}',
trigger: function (res) {
//alert('用户点击发送给朋友');
},
success: function (res) {
//alert('已分享');
},
cancel: function (res) {
//alert('已取消');
},
fail: function (res) {
//alert(JSON.stringify(res));
}
};
var shareQQObj = {
title: '${shareTitle}',
desc: '分享描述',
link: '${shareQQUrl}',
imgUrl: '${shareImg}',
trigger: function (res) {
//alert('用户点击发送给朋友');
},
success: function (res) {
//alert('${shareQQUrl}');
},
cancel: function (res) {
//alert('已取消');
},
fail: function (res) {
//alert(JSON.stringify(res));
}
};
//分享朋友
wx.onMenuShareAppMessage(shareObj);
//分享朋友圈
wx.onMenuShareTimeline(shareObj);
//分享到QQ
wx.onMenuShareQQ(shareQQObj);
//分享到QQ空间
wx.onMenuShareQZone(shareQQObj);
});
</script>
后端服务代码:
对于微信分享功能,后端服务需要将如下信息提供给前端:
a. APPID
b. 分享标题——shareTitle,
c.分享描述——shareDesc,
d.分享地址——shareUrl,
e.分享缩略图——shareImg,
f.微信配置信息——jsapi_ticket、随机数(noncestr)、时间戳(timestamp)、地址(url)、签名(signature)
具体代码如下:
@Override
public String getShareInfo(String jsonParam) {
Map<String, Object> result = new HashMap<>();
ReturnCodeUtils.initParms(result);
Map<String, Object> data = new HashMap<>();
try {
//appid
String appid=props.getAppid();
JSONObject jsonObject=JSONObject.fromObject(jsonParam);
if (!jsonObject.has("pageUrl")) {
ReturnCodeUtils.error(result, ReturnCode.PARAM_ERROR_302.getCode());
}else {
//href
String href= jsonObject.getString("pageUrl");
//页面参数
String params="";
String content = "分享描述";
WxSignature ws = new WxSignature();
//
// 微信签名,刷新access_token和Jsticket
wxj.refreshAccessTokenAndJsticket();
ws.setJsapi_ticket(WeixinConstants.JSAPI_TICKET.getTicket());//
ws.setNoncestr(CommonUtils.getRandomString(8));//noncestr
ws.setTimestamp(String.valueOf(CommonUtils.getNowTimeStampStr()));//timestamp
ws.setUrl(href);
logger.info("=================="+"jsapi_ticket=" + WeixinConstants.JSAPI_TICKET.getTicket() + "&noncestr="
+ ws.getNoncestr() + "×tamp=" + ws.getTimestamp() + "&url=" + ws.getUrl());
ws.setSignature(DigestUtils.sha1Hex("jsapi_ticket=" + WeixinConstants.JSAPI_TICKET.getTicket() + "&noncestr="
+ ws.getNoncestr() + "×tamp=" + ws.getTimestamp() + "&url=" + ws.getUrl()));//signature
data.put("shareTitle", content);//分享标题
data.put("shareDesc", "分享描述");
data.put("shareUrl",
"https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + props.getAppid() + "&redirect_uri="
+ systemUrl + "/H5/index.html#/orderBill&response_type=code&scope=snsapi_base&state=" + params
+ "#wechat_redirect");//分享到微信的url地址
data.put("shareQQUrl", systemUrl + "/H5/index.html#/orderBill");// 普通分享url地址
data.put("shareImg", systemUrl + "/H5/static/images/share_img.jpg");
data.put("share", ws);
data.put("appid", appid);
ReturnCodeUtils.success200(result, data);
}
} catch (Exception e) {
logger.error("获取分享信息service异常:" + e.getMessage(), e);
logger.error("获取分享信息service异常,入参:" + jsonParam);
}
String res=JSONObject.fromObject(result).toString();
return res;
}
注:生成的签名是一个动态的url地址+时间戳(timestamp)+随机数( nonceStr)生成的。而如果是html的静态页面在前端通过ajax将url传到后台签名,前端需要用js获取当前页面除去'#'hash部分的链接(可用location.href.split('#')[0]获取,而且需要encodeURIComponent),因为页面一旦分享,微信客户端会在你的链接末尾加入其它参数,如果不是动态获取当前链接,将导致分享后的页面签名失败。如果是jsp页面,则需要通过systemUrl+request.getQueryString()来获取。
8.关于分享统计的设计思路
关于分享的统计这一部分内容,因为我暂时还没有做,但是这一部分内容同样是非常常用的,毕竟在我们具体的业务中,只要有了分享,那么分享的次数的统计是必不可少的,所以在此先说一下设计思路。
首先,我们要知道分享的链接里只有state一个参数可以携带我们具体业务的参数,所以我们要将所有的参数都放到这一个key里。经过尝试,state的参数可以是json格式的。
我们在做分享统计的时候,就可以先获取当前用户的openid然后拼接到参数里,这样我们每次做分享的时候,都把当前的openid保存,形成一个openid的链,然后将每次分享打开的链接做一个流水记录。这样,我通过计算openid的链有几级就能知道具体的分享次数了。
当然,这种方式仅仅是一个理论上的描述,具体实践还可以再此基础上做出适当的调整。
三、总结
这次的微信功能开发,就涉及到了这些内容。其中一些内容是比较基础的,所以对于初学者来说,是需要知道的。只有清楚了基本的内容,那微信的网页开发也就大同小异了。以上就是自己对微信的理解,如果哪位前辈觉得有什么不对的地方,还请不吝赐教。