微信公众号开发三

标签: 微信 分类: Javascript 创建时间:2020-03-06 06:19:58 更新时间:2025-01-17 10:39:23

1.分享

微信公众号的分享,有诸多限制,比如
(1) 分享按钮的位置不能自定义
分享按钮,只能调用微信自带的右上角的那个三个点,用他的功能打开底部的分享功能,而不能像有些app一样,自己将分享按钮定义在页面顶部或者是自定义底部的分享按钮样式。

(2) 分享的连接只能是安全域名定义的链接
如果定义的链接不是当前jssdk签名的页面,那么微信就会将其指定为默认的当前也的url。

(3) 不能动态拼接
比如我想这个页面中的一个按钮分享的是这个链接,一个按钮分享的是另外一个链接,这是不允许的,在页面首次加载调用ready时,分享的链接就已经确定好了,微信是什么链接,朋友圈是什么链接,都初始话好了,不能再次更改了。

我的想法是这样的,也参考了其他的公众号的做法。点击分享按钮是,将网页跳转到定义好分享链接的页面(或者是空页面),然后在这个页面请求jssdk签名,调用wx.ready()方法,然后调用onMenuShareAppMessage、onMenuShareTimeline等方法,其中的link就指向了当前页面获得签名的location.href。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
wx.ready(function () {
wx.onMenuShareTimeline({
title: title, // 分享标题
link: link, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: imgUrl, // 分享图标
success: function () {
// 用户确认分享后执行的回调函数
},
cancel: function () {
// 用户取消分享后执行的回调函数
}
})
wx.onMenuShareAppMessage({
title: title, // 分享标题
desc: desc, // 分享描述
link: link, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: imgUrl, // 分享图标
type: '', // 分享类型,music、video或link,不填默认为link
dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
success: function () {
// 用户确认分享后执行的回调函数
},
cancel: function () {
// 用户取消分享后执行的回调函数
}
})
wx.onMenuShareQQ({
title: title, // 分享标题
desc: desc, // 分享描述
link: link, // 分享链接
imgUrl: imgUrl, // 分享图标
success: function () {
// 用户确认分享后执行的回调函数
},
cancel: function () {
// 用户取消分享后执行的回调函数
}
})
wx.onMenuShareQZone({
title: title, // 分享标题
desc: desc, // 分享描述
link: link, // 分享链接
imgUrl: imgUrl, // 分享图标
success: function () {
// 用户确认分享后执行的回调函数
},
cancel: function () {
// 用户取消分享后执行的回调函数
}
})
})

跳到分享页面之后,这个页面产生一个蒙版,蒙版上有一个箭头,箭头指向右上角三个点,给用户一个提示,意思就是说,你去点这里吧。

参考文章:
1.关于微信分享中的wx.ready()
2.微信自定义分享动态配置title、url等 (这篇文章通过设置了一个全局对象进行了动态参数配置,没有实际的测试过,不知道可以不可以)
3.Vue中动态生成微信分享链接和分享文字 (这里也提到了使用vue的路由进行动态生成分享文字)
4.【解决方案】微信网页链接分享自定义
5.微信分享填坑指南 (这篇文章写的注意事项比较多)

2.自定义菜单

微信公众号支持通过程序创建自定义菜单,修改自定义菜单的步骤如下:
(1) 打开测试接口为地址

(2) 生成access_token
access_token要事先生成,同样的在测试地址中,选择获取access_token接口/token,然后就是填入自己的appid和secret 生成相应的access_token。

(3) 修改菜单内容
选择自定义菜单->自定义菜单创建接口/menu/create,填入access_token,body中填入菜单的json字符串,如下内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
{
"button": [
{
"type": "view",
"name": "公司网站",
"url": "",
"sub_button": [ ]
},
{
"name": "数据平台",
"sub_button": [
{
"type": "view",
"name": "1.0",
"url": "",
"sub_button": [ ]
}
]
},
{
"name": "用户服务",
"sub_button": [
{
"type": "view",
"name": "用户注册",
"url": "",
"sub_button": [ ]
}
{
"type": "view",
"name": "新版演示",
"url": "",
"sub_button": [ ]
}
]
}
]
}

(4) 点击检查问题,就可以创建自定义菜单了。过个几分钟,自定义菜单就可以生效了。

注意,这里虽然是debug,但是自定义的菜单也会在公众号上生效。

问题

1.请输入http://或https://开头的公众号相关链接
在自定义菜单的时候,出现这个错误是因为订阅号没有进行认证,不允许填写第三方外链。

3.获取access_token

access_token是微信公众号的接口调用凭证,使用app_id和app_secret,通过 "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+app_id+"&secret="+app_secret 方式获取。 刚开始的时候,我觉得获取access_token挺简单的,使用一个get请求就可以了,然后保存到redis中,但是随着应用程序的增加,好多地方都要用到这个access_token,设置程序部署到多个服务器上,这个时候,我才发现,官网上建议创建中控服务器是多么的重要,因为access_token是有时效的,这个应用获取了,可以使用,但是这个时候另一台服务器上的另外的应用程序也需要这个token,这个时候再通过app_id和app_secret进行申请新的,老的就不能使用了,于是就会造成混乱的结果。

参考文章:
1.接口调用请求说明 (官方对微信access_token的说明)
2.wechat4j (这是wechat4j一个小的工具集合)
3.easywechat (另外一个封装的微信SDK,比上一个的star人数要多的多了,但是这个项目是php版本的)
4. Wechat-Group/WxJava (我怀疑是微信团队出品的集成sdk,地下还附带了很多开源的项目:基于微信公众号的签到、抽奖、发送弹幕程序,微同商城,专注批量推送的小而美的工具,wx-manage,基于若依开发的微信公众号管理系统)

4.网页授权获取用户的信息

获取网页授权,只能是服务号才可以,订阅号不可以,获取用户信息和网页授权流程分为四步:

1.引导用户进入授权页面同意授权,获取code

1
2
3
4
5
6
7
8
9
10
11
12
@RequestMapping(value = "/wxlogin")
public void wxlogin(@RequestParam(value = "sharecode")String sharecode,
@RequestParam(value = "devicecode")String devicecode, HttpServletResponse response){
try {
String url="https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appid + "&redirect_uri="
+ URLEncoder.encode(wxauthurl+"/wxcode?sharecode="+sharecode+"&devicecode="+devicecode, "UTF-8") +
"&response_type=code&scope="+ appgrantscope + "&state=www.proheng.com#wechat_redirect";
response.sendRedirect(url);
}catch (Exception e){
log.error("wxlogin",e);
}
}

2.通过code换取网页授权access_token(与基础支持中的access_token不同)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 根据临时code换取微信access_token,然后可以通过微信access_token获取到其他的信息
// 因为这个code只能消费一次,如果这里消费了,那么跳转的地址就不能继续消费了
String urlToken = "https://api.weixin.qq.com/sns/oauth2/access_token?"+"appid=" + appid + "&secret="
+ appsecret + "&code=" + code + "&grant_type=authorization_code";

// 发起授权
HttpRequest httpRequest= HttpRequest.get(urlToken);
String tokenStr= httpRequest
.execute().body();
log.error("用户授权返回信息:"+tokenStr);
// 解析授权结果
JSONObject wxuserauthinfo = JSONObject.parseObject(tokenStr);
// 获取信息失败,返回登陆页面
if(wxuserauthinfo.getString("errcode")!=null){
log.error(tokenStr);
}

3.如果需要,开发者可以刷新网页授权access_token,避免过期

4.通过网页授权access_token和openid获取用户基本信息(支持UnionID机制)

1
2
3
4
5
6
7
8
9
10
11
12
13
// 获取微信昵称
String urlUserInfo = "https://api.weixin.qq.com/sns/userinfo?"+"access_token=" + access_token + "&openid" +
"="+openid+"&lang=zh_CN";
httpRequest= HttpRequest.get(urlToken);
String userStr= httpRequest
.execute().body();
log.error("用户信息接口返回信息:"+userStr);
JSONObject wxuserinfo=JSONObject.parseObject(userStr);
// 获取信息失败,返回登陆页面
if(wxuserinfo.getString("errcode")!=null){
log.error(tokenStr);
}
String nickname=wxuserinfo.getString("nickname");

5.跳转小程序

可以使用标签 wx-open-launch-weapp 实现小程序跳转。
(1) 绑定域名

(2) 引入JS文件

(3) 配置jssdk,从后台获取签名信息

1
2
3
4
5
6
7
8
9
wx.config({
debug: true,
appId: 'wx11c8c19b9d0c8642', // 已认证的小程序appid或已认证的服务号appid
timestamp: ${timestamp!''}, // 必填,使用小程序云开发静态网站托管的网页填任意数字即可,无须鉴权
nonceStr: '${nonceStr!''}', // 必填,使用小程序云开发静态网站托管的网页填任意非空字符串即可,无须鉴权
signature: '${signature!''}', // 必填,使用小程序云开发静态网站托管的网页填任意非空字符串即可,无须鉴权
jsApiList: ['chooseImage'], // 安卓上必填一个,随机即可
openTagList: ['wx-open-launch-weapp','wx-open-launch-app'], // 填入打开小程序的开放标签名
})

(4) 引入标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<wx-open-launch-weapp
id="launch-btn"
appid="wx12345678"
path="pages/home/index?user=123&action=abc"
>
<script type="text/wxtag-template">
<style>.btn { padding: 12px }</style>
<button class="btn">打开小程序</button>
</script>
</wx-open-launch-weapp>
<script>
var btn = document.getElementById('launch-btn');
btn.addEventListener('launch', function (e) {
console.log('success');
});
btn.addEventListener('error', function (e) {
console.log('fail', e.detail);
});
</script>

参考文章:
1.跳转小程序:wx-open-launch-weapp
2.开放标签说明文档 开发标签说明文档。

wx-open-launch-weapp 标签不显示

我遇到的问题就是,签名正确,但是这个按钮还是出不来。我尝试了很多的方法,费了很大的劲,在服务器上,本地上,都解决了 jssdk 的签名错误,已经认证成功了。结果显示,配置的 openTagList 为空。

我又仔细的查阅了这个开发文档,里面有这么一句话,开放对象:

1.已认证的服务号,服务号绑定“JS接口安全域名”下的网页可使用此标签跳转任意合法合规的小程序。
2.已认证的非个人主体的小程序,使用小程序云开发的静态网站托管绑定的域名下的网页,可以使用此标签跳转任意合法合规的小程序。

我发现我用的签名和appid是一个订阅号,而不是一个服务号。难道是这个原因吗?

【解决方案】
最后的解决方案,我用了一个服务号,而不是订阅号,最终实现了 wx-open-launch-weapp 的显示。

参考文章:
1.wx-open-launch-weapp按钮不显示,怎么回事? 这里说要在 ready 方法内
2.H5打开小程序:按钮不显示的相关问题解决 1.signature不正确.2.微信weixinjs引入的版本问题.
3.微信h5跳转小程序wx-open-launch-weapp开放标签不显示(已解决) 这个问题是因为jweixin版本不同。
4.h5 打开小程序 wx-open-launch-weapp 踩坑
5.微信内网页跳转APP功能 1.由于“微信开放标签”只开放给 JS 接口安全域名,使用此功能前请确保网页所属的域名已绑定为服务号的 JS 接口安全域名。2.微信内网页无法跳转任意的 APP 。开发者需要在“微信开放平台”登记域名与移动应用(APP)的绑定关系,网页只可以跳转其域名绑定的移动应用(APP)
6.已经认证的公众号,为什么无法使用开放标签? 请问下这个公众号为认证的订阅号, 可以使用openTagList吗? 现在返回为空。
小额赞助
本人提供免费与付费咨询服务,感谢您的支持!赞助请发邮件通知,方便公布您的善意!
**光 3.01 元
Sun 3.00 元
bibichuan 3.00 元
微信公众号
广告位
诚心邀请广大金主爸爸洽谈合作
每日一省
isNaN 和 Number.isNaN 函数的区别?

1.函数 isNaN 接收参数后,会尝试将这个参数转换为数值,任何不能被转换为数值的的值都会返回 true,因此非数字值传入也会返回 true ,会影响 NaN 的判断。

2.函数 Number.isNaN 会首先判断传入参数是否为数字,如果是数字再继续判断是否为 NaN ,不会进行数据类型的转换,这种方法对于 NaN 的判断更为准确。

每日二省
为什么0.1+0.2 ! == 0.3,如何让其相等?

一个直接的解决方法就是设置一个误差范围,通常称为“机器精度”。对JavaScript来说,这个值通常为2-52,在ES6中,提供了Number.EPSILON属性,而它的值就是2-52,只要判断0.1+0.2-0.3是否小于Number.EPSILON,如果小于,就可以判断为0.1+0.2 ===0.3。

每日三省
== 操作符的强制类型转换规则?

1.首先会判断两者类型是否**相同,**相同的话就比较两者的大小。

2.类型不相同的话,就会进行类型转换。

3.会先判断是否在对比 null 和 undefined,是的话就会返回 true。

4.判断两者类型是否为 string 和 number,是的话就会将字符串转换为 number。

5.判断其中一方是否为 boolean,是的话就会把 boolean 转为 number 再进行判断。

6.判断其中一方是否为 object 且另一方为 string、number 或者 symbol,是的话就会把 object 转为原始类型再进行判断。

每日英语
Happiness is time precipitation, smile is the lonely sad.
幸福是年华的沉淀,微笑是寂寞的悲伤。