使用JSSDK实现微信自定义分享

1. 准备工作

1.1 查看公众号分享接口权限

要使用微信SDK必须要有经过微信认证的非个人服务号

登陆服务号后,在开发-》接口权限 查询有没有**分享**接口的权限

[image:45AC64AB-5536-4FDF-8382-DA42B464D5FD-21376-00003687F3F4D657/35B783F4-9CDA-47F4-9590-2A4285D5A723.png]

1.2 分享页面的域名需ICP备案,服务端口号为80或43

1.3 用于分享显示的图片大小大于300*300

2. 公众号管理员设置

2.1  设置js安全域名

登陆公众号后,在设置-》公众号设置-》功能设置-》js接口安全域名

2.1.1 管理员添加页面的域名

2.1.2 管理员下载验证文件,开发人员上传文件到域名指向的服务器根目录

2.2 设置ip白名单

登陆公众号后,在开发-》基本配置

2.2.1 提供appId, appSecret给开发人员,用于获取access_token

2.2.2 将服务器ip地址添加到ip白名单中

正式公众号每个自然月只能修改3次域名,并且每个接口的调用次数有限,所以测试环境下,可以注册一个测试号用于测试

[image:93836452-7373-4808-A914-81CE1960220A-22465-000026824B30DE10/BF8111AA-87D5-442A-90A3-A2B92933318B.png]

点击微信公众平台测试账号,即生成测试号,测试号的调用接口次数可以无上限。

在js安全域名设置测试页面的域名

[image:8A9DDF2B-0F0D-434D-82C7-7B8DB7EBE1CE-22465-00002A96DAAB3B99/695FA033-C02B-4A14-8F6F-6FD7180C15B9.png]

记录测试号的appId和appSecret

测试号的接口调用需要先关注测试账号,才能使用

3. 前端页面配置

3.1. 引入js文件

在需要调用js接口的页面引入如下文件

http://res.wx.qq.com/open/js/jweixin-1.2.0.js

生产环境如果是https, 必须用https

3.2. 通过config接口注入权限验证配置

所有需要使用js-sdk的页面需先注入配置信息,否则将无法使用,同一个url仅需调用一次

```

wx.config({

    debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。

    appId: '', // 必填,公众号的唯一标识

    timestamp: , // 必填,生成签名的时间戳

    nonceStr: '', // 必填,生成签名的随机串

    signature: '',// 必填,签名

    jsApiList: [‘onMenuShareTimeline’,’onMenuShareAppMessage’] // 必填,需要使用的JS接口列表

});

```

分享相关js api

> onMenuShareTimeline 分享到朋友圈

> onMenuShareAppMessage 分享给朋友

> onMenuShareQQ 分享到qq

> onMenuShareWeibo 分享到微博

> onMenuShareQZone 分享打qq空间

我的代码

```

wx.config({

debug: true,

appId: signInfo.appId,

timestamp: signInfo.timestamp,

nonceStr: signInfo.nonceStr,

signature: signInfo.signature,

jsApiList: ['onMenuShareTimeline','onMenuShareAppMessage','onMenuShareQQ','onMenuShareWeibo','onMenuShareQZone']

});

```

appId, timestamp, nonceStr, signature前后端都要保持一致,所以都从后台接口返回比较好

3.3. 通过ready接口处理成功验证

wx.ready(function(){})

config是异步操作,页面加载时就需要调用的接口需要在ready函数中来执行,用户触发的接口可以直接调用,不需放在ready中

3.4. 通过error接口处理失败验证

wx.error(function(res){})

config信息验证失败回执行error方法,spa可以在这里更新签名

我的代码

```

wx.error(function (res) {

console.log('微信认证失败: ',res.errMsg);

});

```

3.5. 获取“分享到朋友圈”按钮点击状态及自定义分享内容接口

wx.onMenuShareTimeline({

    title: '', // 分享标题

    link: '', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致

    imgUrl: '', // 分享图标

    success: function () {

    // 用户确认分享后执行的回调函数

},

cancel: function () {

    // 用户取消分享后执行的回调函数

    }

});

我的代码

```

wx.ready(function () {

wx.onMenuShareTimeline({

title: '办人事,就上HR-X',

link: url,

imgUrl: 'https://bpic.588ku.com/back_pic/05/49/38/775ac8cbfa1e6e4.jpg',

});

wx.onMenuShareAppMessage({

title: '办人事,就上HR-X',

desc: '最牛的人事App',

link: url,

imgUrl: 'https://bpic.588ku.com/back_pic/05/49/38/775ac8cbfa1e6e4.jpg',

})

});

```

4. 服务器签名算法

出于安全和全局可用性考虑,签名接口需在服务端实现,并且提供全局缓存。

微信官方给出了签名算法各语言的版本

[微信签名算法各语言版本](https://link.jianshu.com/?t=http://demo.open.weixin.qq.com/jssdk/sample.zip)

4.1 获取access_token

获取access_token需要公众号的appId和appSecret

access_token是公众号的全局唯一接口调用凭据,公众号调用各接口都需要使用access_token, 有效期expire_in为2个小时,需在有效期内定期刷新。每日限额2000次

https请求方式: GET

https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

正常情况下,微信会返回下述JSON数据包给公众号:

{"access_token":"ACCESS_TOKEN","expires_in":7200}

4.2 获取jsapi_ticket

jsapi_ticket是公众号用于调用微信JS接口的临时票据,有效期为7200s,频繁调用会导致api调用受限,获取jsapi_ticket之后,需在自己的服务器全局缓存

https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi

4.3 生成签名

参与签名的字段包括有效的jsapi_ticket, noncestr(随机字符串), timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分)

对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1

对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义

例如

```

jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg

noncestr=Wm3WZYTPz0wzccnW

timestamp=1414587457

url=http://mp.weixin.qq.com?params=value

string1=jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW& timestamp =1414587457&url=http://mp.weixin.qq.com?params=value

signature = 0f9de62fce790f9a083d5c99e95740ceb90c27ed

```

注意事项

1.签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同。

2.签名用的url必须是调用JS接口页面的完整URL不包括 ‘#’号部分,前端页面调用接口时传递给后台

3.出于安全考虑,开发者必须在服务器端实现签名的逻辑。

5. 测试效果

测试以上配置是否生效,我们需要搭建测试环境

a. 测试公众号

b. 可连接外网的后台接口

c. 有外网可访问域名的前端页面

d. 微信web开发者工具

5.1 测试公众号

同2.2中方法申请测试公众号

5.2 可连接外网的后台接口

后台接口需要请求微信的token和ticket接口,所以需要访问外网

接口部署在外网可访问的服务器上

5.3 有外网可访问域名的前端页面

微信jssdk接口需要在公众号设置js安全域名,如果是本机联调,该域名就需要配置成本地服务的域名,但局域网内的计算机,外网无法访问,那就需要通过ngrok,实现内网穿透

[ngrok - download](https://ngrok.com/download)

ngrok的安装使用如下

[image:B724618A-2091-4AF7-956D-4B0B9AEE4C24-22465-00002C90AFB5B803/3981CEAE-C53B-4B0C-BB90-0C47540880C2.png]

不需要注册直接跳过第3步就可以使用

使用步骤

在本地启动web服务,如端口是3000(一般用户不允许使用80端口,如果要使用80端口需要超级用户)

运行./ngrok http 3000

待状态是online 看看到映射后的域名

[image:1BE9FBF7-BA2F-4BD3-BFEE-A4776AEDA1E8-22465-00002D32F626B6D4/EB0C575A-A27D-4917-A641-C181BD3A43D7.png]

将该域名填到公众号的js安全域名里

5.4 微信web开发者工具

pc浏览器无法模拟微信浏览器测试微信接口

可以通过手机浏览器扫码打开上述地址测试,但不能查看日志和调试

另一种方式是使用微信开发者工具,模拟微信浏览器,又集成了chromedev调试工具,可以在电脑上直接打开网页调试微信接口

微信开发者工具有两个版本,一个版本只有web网页调试功能,另一个版本集成了小程序调试和网页调试的功能,推荐下载集成了小程序功能版本

[全新微信开发者工具](https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html)

[image:41214C28-4227-472A-BD2C-2A34BD5873A4-22465-00002E96DEE30993/25902EC9-CCE0-4C98-89DF-4E8B6ED5A755.png]

打开之后,选择公众号网页项目,就可以打开带有chromedev调试工具的微信浏览器了。

当然这个浏览器相比chrome浏览器会慢很多

6. 彩蛋

最后,如果你能看到最后,送给大家一个彩蛋,一套前后端都已实现的源码,下载代码后,配置node,npm环境,替换代码中的网页域名,appId, appSecret, 在自己公众号配置网页域名,最后运行npm run start就可以启动服务了,手机微信或微信开发者工具打开就可以查看效果。

[源码地址](https://github.com/scarlettxu/wechat-signature)

7. 其他

实际项目中,按照文档配置了,可能还会出问题,需要注意一下注意事项

7.1 注意事项

* url: 需要根据不同的页面动态获取,url不能进行encodeURIComponent,否则验签会失败 url不能包括微信添加的’#‘后边的部分,所以应该处理为:window.location.href.split(‘‘)[0] 签名用的url必须是调用JS接口页面的完整URL。

* nonceStr、timestamp:应该动态生成,而不能hardcode 签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同

* accesstoken:同调用微信其他接口的accesstoken,必须全局缓存,以免影响其他业务,即是说:微信所有业务应该用同一个accesstoken去调用微信接口,而不能自己刷新accesstoken。

* ticket:同accesstoken一样,必须全局缓存,方式很多,可以放到数据库,或者放到缓存。目前ticket的有效时间为2小时,所以2小时内ticket未过期时,不能重复获取,否则可能导致ticket获取次数超过限额,导致sign失败

7.2 官方常见问题及处理办法

1、invalid url domain

当前页面所在域名与使用的appid没有绑定,请确认正确填写绑定的域名,如果使用了端口号,则配置的绑定域名也要加上端口号(一个appid可以绑定三个有效域名,见 目录1.1.1)。

2、invalid signature签名错误。

建议按如下顺序检查:

确认签名算法正确,可用 http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign 页面工具进行校验。

确认config中nonceStr(js中驼峰标准大写S), timestamp与用以签名中的对应noncestr, timestamp一致。

确认url是页面完整的url(请在当前页面alert(location.href.split(‘#’)[0])确认),包括’http(s)://’部分,以及’?’后面的GET参数部分,但不包括 hash后面的部分。

确认 config 中的 appid 与用来获取 jsapi_ticket 的 appid 一致。

确保一定缓存access_token和jsapi_ticket。

确保你获取用来签名的url是动态获取的,动态页面可参见实例代码中php的实现方式。 如果是html的静态页面在前端通过ajax将url传到后台签名,前端需要用js获取当前页面除去’#’hash部分的链接,获取,而且需要encodeURIComponent),因为页面一旦分享,微信客户端会在你的链接末尾加入其它参数,如果不是动态获取当前链接,将导致分享后的页面签名失败。

3、the permission value is offline verifying

这个错误是因为config没有正确执行,或者是调用的JSAPI没有传入config的jsApiList参数中。建议按如下顺序检查:

确认config正确通过。

如果是在页面加载好时就调用了JSAPI,则必须写在wx.ready的回调中。

确认config的jsApiList参数包含了这个JSAPI。

4、permission denied

该公众号没有权限使用这个JSAPI,或者是调用的JSAPI没有传入config的jsApiList参数中(部分接口需要认证之后才能使用)。

5、function not exist

当前客户端版本不支持该接口,请升级到新版体验。

6、为什么6.0.1版本config:ok,但是6.0.2版本之后不ok

因为6.0.2版本之前没有做权限验证,所以config都是ok,但这并不意味着你config中的签名是OK的,请在6.0.2检验是否生成正确的签名以保证config在高版本中也ok。

7、在iOS和Android都无法分享

请确认公众号已经认证,只有认证的公众号才具有分享相关接口权限,如果确实已经认证,则要检查监听接口是否在wx.ready回调函数中触发

8、服务上线之后无法获取jsapi_ticket,自己测试时没问题。

因为access_token和jsapi_ticket必须要在自己的服务器缓存,否则上线后会触发频率限制。请确保一定对token和ticket做缓存以减少2次服务器请求,不仅可以避免触发频率限制,还加快你们自己的服务速度。目前为了方便测试提供了1w的获取量,超过阀值后,服务将不再可用,请确保在服务上线前一定全局缓存access_token和jsapi_ticket,两者有效期均为7200秒,否则一旦上线触发频率限制,服务将不再可用。

9、uploadImage怎么传多图

目前只支持一次上传一张,多张图片需等前一张图片上传之后再调用该接口

10、没法对本地选择的图片进行预览

chooseImage接口本身就支持预览,不需要额外支持

11、通过a链接(例如先通过微信授权登录)跳转到b链接,invalid signature签名失败

后台生成签名的链接为使用jssdk的当前链接,也就是跳转后的b链接,请不要用微信登录的授权链接进行签名计算,后台签名的url一定是使用jssdk的当前页面的完整url除去’#’部分

12、出现config:fail错误

这是由于传入的config参数不全导致,请确保传入正确的appId、timestamp、nonceStr、signature和需要使用的jsApiList

13、如何把jsapi上传到微信的多媒体资源下载到自己的服务器

请参见文档中uploadVoice和uploadImage接口的备注说明

14、Android通过jssdk上传到微信服务器,第三方再从微信下载到自己的服务器,会出现杂音

微信团队已经修复此问题,目前后台已优化上线

15、绑定父级域名,是否其子域名也是可用的

是的,合法的子域名在绑定父域名之后是完全支持的

16、在iOS微信6.1版本中,分享的图片外链不显示,只能显示公众号页面内链的图片或者微信服务器的图片,已在6.2中修复

17、是否需要对低版本自己做兼容

jssdk都是兼容低版本的,不需要第三方自己额外做更多工作,但有的接口是6.0.2新引入的,只有新版才可调用

18、该公众号支付签名无效,无法发起该笔交易

请确保你使用的jweixin.js是官方线上版本,不仅可以减少用户流量,还有可能对某些bug进行修复,拷贝到第三方服务器中使用,官方将不对其出现的任何问题提供保障,具体支付签名算法可参考 JSSDK微信支付一栏

19、目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题已在Android6.2中修复

20、uploadImage在chooseImage的回调中有时候Android会不执行

Android6.2会解决此问题,若需支持低版本可以把调用uploadImage放在setTimeout中延迟100ms解决

21、require subscribe错误说明你没有订阅该测试号,该错误仅测试号会出现

22、getLocation返回的坐标在openLocation有偏差

因为getLocation返回的是gps坐标,openLocation打开的腾讯地图为火星坐标,需要第三方自己做转换,6.2版本开始已经支持直接获取火星坐标

23、查看公众号(未添加): “menuItem:addContact”不显示

目前仅有从公众号传播出去的链接才能显示,来源必须是公众号

24、ICP备案数据同步有一天延迟,所以请在第二日绑定

8. 测试号和公众号的差别

域名

公众号域名必须备案,测试号域名不需备案

公众号域名仅支持80端口,测试号域名支持端口号

公众号域名所在服务器需要配置验证文件,测试号不需要配置验证文件

公众号需要配置ip白名单才能调用token几口,测试号不需要配置ip白明白

有端口号的域名一定要带上端口号

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容