登录你的微信平台,点击“公众号设置”。
2
点击“功能设置”,然后点击“设置”。
3
设置JS接口安全域名。这里填写的是一级域名,不带www和http。最多可以设置三个域名。设置完后点击确定。(多说一句,相比以前的分享没有任何域名限制,这里设置安全域名,目的是为了当发现此公众平台发现诱导分享行为时,可以根据此域名追溯到所有分享出去的链接,以及通过这些链接增加的粉丝。这样,微信就可以牢牢控制了你的微信平台,一旦发现违规,让分享链接失效,删除掉诱导行为增加的粉丝,是瞬间就可以完成的。因此,微信平台的开发者,一定要合理来使用分享功能,不要因小失大。等到你的微信平台被封,估计哭都来不及)
4
在开发者中心中获取你的AppID和AppSecret,接下来在获取令牌时,需要这两个信息。
5
获取令牌。在服务器端完成,代码如下:
function wx_get_token() {
$token = S('access_token');
if (!$token) {
$res = file_get_contents('https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' .'你的AppID'.'&secret=' .'你的AppSecret');
$res = json_decode($res, true);
$token = $res['access_token'];
// 注意:这里需要将获取到的token缓存起来(或写到数据库中)
// 不能频繁的访问https://api.weixin.qq.com/cgi-bin/token,每日有次数限制
// 通过此接口返回的token的有效期目前为2小时。令牌失效后,JS-SDK也就不能用了。
// 因此,这里将token值缓存1小时,比2小时小。缓存失效后,再从接口获取新的token,这样
// 就可以避免token失效。
// S()是ThinkPhp的缓存函数,如果使用的是不ThinkPhp框架,可以使用你的缓存函数,或使用数据库来保存。
S('access_token', $token, 3600);
}
return $token;
}
注意:返回的access_token长度至少要留够512字节。接口返回值:
{"access_token":"ACCESS_TOKEN","expires_in":7200}
{"access_token":"vdlThyTfyB0N5eMoi3n_aMFMKPuwkE0MgyGf_0h0fpzL8p_-0kVHY33BykRC0YXZZZ-WdxEic4","expires_in":7200}
6
获取jsapi的ticket。jsapi_ticket是公众号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。
function wx_get_jsapi_ticket(){
$ticket = "";
do{
$ticket = S('wx_ticket');
if (!empty($ticket)) {
break;
}
$token = S('access_token');
if (empty($token)){
wx_get_token();
}
$token = S('access_token');
if (empty($token)) {
logErr("get access token error.");
break;
}
$url2 = sprintf("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=jsapi",
$token);
$res = file_get_contents($url2);
$res = json_decode($res, true);
$ticket = $res['ticket'];
// 注意:这里需要将获取到的ticket缓存起来(或写到数据库中)
// ticket和token一样,不能频繁的访问接口来获取,在每次获取后,我们把它保存起来。
S('wx_ticket', $ticket, 3600);
}while(0);
return $ticket;
}
接口返回值:
{"errcode":0,"errmsg":"ok","ticket":"-I98-_YWtOQg","expires_in":7200}
7
签名,将jsapi_ticket、noncestr、timestamp、分享的url按字母顺序连接起来,进行sha1签名。
noncestr是你设置的任意字符串。
timestamp为时间戳。
$timestamp = time();
$wxnonceStr = "任意字符串";
$wxticket = wx_get_jsapi_ticket();
$wxOri = sprintf("jsapi_ticket=%s&noncestr=%s×tamp=%s&url=%s",
$wxticket, $wxnonceStr, $timestamp,
'要分享的url(从http开始,如果有参数,包含参数)'
);
$wxSha1 = sha1($wxOri);
END
步骤2 添加JS代码
生成签名后,就可以使用js代码了。在你的html中,进行如下设置即可。
<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,
appId: "你的AppID",
timestamp: '上一步生成的时间戳',
nonceStr: '上一步中的字符串',
signature: '上一步生成的签名',
jsApiList: ['onMenuShareTimeline', 'onMenuShareAppMessage'] // 功能列表,我们要使用JS-SDK的什么功能
});
// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在 页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready 函数中。
wx.ready(function(){
// 获取“分享到朋友圈”按钮点击状态及自定义分享内容接口
wx.onMenuShareTimeline({
title: '分享标题', // 分享标题
link:"分享的url,以http或https开头",
imgUrl: "分享图标的url,以http或https开头" // 分享图标
});
// 获取“分享给朋友”按钮点击状态及自定义分享内容接口
wx.onMenuShareAppMessage({
title: '分享标题', // 分享标题
desc: "分享描述", // 分享描述
link:"分享的url,以http或https开头",
imgUrl: "分享图标的url,以http或https开头", // 分享图标
type: 'link', // 分享类型,music、video或link,不填默认为link
});
});
</script>
2. 微信公众平台开发,oauth2.0认证地址,打开jssdk页面无法验证通过
给你个PHP的例子:
下面的代码保存为get_sdkper.php
<?php
require_once "jssdk.php";
//1.注意:所有的JS接口只能在公众号绑定的域名下调用,公众号开发者需要先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。
//2.填写appid和secret
$appid="你的appid";
$secret="你的secret";
$getUrl=$_POST["url"];
$jssdk = new JSSDK($appid, $secret,$getUrl);
$signPackage = $jssdk->GetSignPackage();
echo("{\"appId\":\"".$signPackage["appId"]."\",\"timestamp\":\"".$signPackage["timestamp"]."\",\"nonceStr\":\"".$signPackage["nonceStr"]."\",\"signature\":\"".$signPackage["signature"]."\",\"url\":\"".$signPackage["url"]."\"}");
?>
下面是调用方法:
//调用微信JS API接口
var GetappId="",Gettimestamp="",GetnonceStr="",Getsignature="";
function CallWechatJSAPI()
{
$.ajax({
url:"get_sdkper.php",
type:"POST",
data:"url="+escape(location.href.split('#')[0]),
dataType:"JSON",
success:function(result){
var resultData = $.evalJSON(result);
if(resultData){
GetappId = resultData.appId;
Gettimestamp = resultData.timestamp;
GetnonceStr = resultData.nonceStr;
Getsignature = resultData.signature;
wx.config({
debug: false,
appId: GetappId,
timestamp: Gettimestamp,
nonceStr: GetnonceStr,
signature: Getsignature,
jsApiList: [
'checkJsApi',
'onMenuShareTimeline',
'onMenuShareQQ',
'onMenuShareWeibo',
'hideMenuItems',
'hideAllNonBaseMenuItem',
'chooseImage',
'previewImage',
'uploadImage',
'downloadImage',
'getNetworkType',
'openLocation',
'getLocation',
'hideOptionMenu',
'closeWindow',
'scanQRCode',
'chooseWXPay',
'openProctSpecificView',
'addCard',
'chooseCard',
'openCard'
]
});
}
},
error:function(){
//alert("连接网络失败,请重试。");
}
});
}
3. 如何在React中调用微信的jsSDK
1. 微信JSSDK使用步骤简介
我们既然是在做基于微信的开发,当然就离不开微信的开发文档了。开始之前希望大家能先去看下《微信JS-SDK说明文档》。那么我们怎么样才能用上微信的JSSDK呢?以下基本步骤就是基于该文档的。
需要注意的是,如果本人下面的描述你看的有点云里雾里的话,我建议你:
回头看下本系列《小白学react》的历史基础文章,特别是《小白学react之altjs的Action和Store》以及《小白学react之打通React Component任督二脉》,或/和:
直接跳过我的描述,在文章后面下载最新的源码,先阅读源码,碰到问题再反过来看文章的描述。
步骤一:绑定域名
先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。
备注:登录后可在“开发者中心”查看对应的接口权限。
这里绑定的时候需要注意不要带前面的http协议头。写法跟上一篇《小白学react之网页获取微信用户信息》中的网页回调域名设置的写法是一样的。
步骤二:引入JS文件
在需要调用JS接口的页面引入如下JS文件,(支持https):
请注意,如果你的页面启用了https,务必引入 :
,否则将无法在iOS9.0以上系统中成功使用JSSDK
因为我们的index.html是通过ejs模版生成的,所以我们只需要在我们的index.ejs中的body部分末尾加入相应的微信jssdk库的引用就好了。
步骤三:通过config接口注入权限验证配置
所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用,目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题会在Android6.2中修复)。
这一步的关键是如何生成正确的签名。这里微信jssdk文档中有给出不同语言版本的签名算法示例大家可以参考。往下我们也会就github上的一个签名算法的封装进行学习。
在我们的实战过程中,签名会在服务器端发生。
react客户端会像之前的获取微信用户信息一样,通过一个restfulApi调用服务器端的api,然后由服务器来生成对应的签名,然后将签名信息返回给客户端。
客户端获取到上面wx.config示例代码中的签名相关信息后,就会调用一个Alt的Action,来触发将获取回来的信息保存到一个跟该Action绑定的jssdk状态管理的Store里面。然后就可以调用wx.config来配置我们需要用到的JS接口列表了。
注意这里的wx这个对象是通过上一步的JS文件引入进来的。我们在react的客户端代码中可以直接通过window.wx对其进行引用:
步骤四:通过ready接口处理成功验证
随后,react客户端负责jssdk状态管理的store会调用wx.ready来监听config配置是否成功,如果成功的话,就会将该store的一个ready状态设置成true。
这样的话,通过AltContainer绑定了该store的相应的Component组件就能知道响应的jssdk的api是否已经准备就绪,可以进行调用了。
步骤五:通过error接口处理失败验证
同理,如果如果配置失败的话,那么就在wx.error这个监听接口中将ready状态设置成false。
2. 生成签名
如前面所述,我们需要用到jssdk的页面必须要要注入调用到的api的配置信息。
而注入JS接口到页面时,我们可以看到,还需要使用到其他一些信息。其中appId我们可以从公众号管理后台获得。signature是跟所访问页面的url关联的一个签名,它有专门的一套算法来生成。另外两个参数nonceStr和signature都是在签名的过程中生成的。
这里通过wx.config传进去这些参数,主要是为了让微信去判断我们生成的签名和微信通过这些信息生成的签名是否一致,如果不一致的话,那么注入到该页面的jsApiListj就失败。
那么我们在服务器这边的签名算法是如何的呢?根据微信开发文档我们需要提供以下4个参数,然后通过sha1算发来生成对应的签名:
noncestr:一个随机字符串,我们随便填写
jsapi_ticket:jsapi_ticket是公众号用于调用微信JS接口的临时票据
timestamp: 签名时间戳。注意这个时间戳需要和上面传入wx.config的时间戳一致
url: 调用JS接口页面的完整URL。我们可以从react客户端通过location.href获得,并传给服务器端
那么这里主要需要解决的就是如何获得jsapi_ticket这个临时票据了。
根据文档的描述,我们可以通过以下这个接口获得:
cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
从中可以看到,我们调用这个接口首先要获得一个access_token。这里微信也有相应的api来处理。
cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
这里需要用到我们的微信公众号的appId和secret,这些我们都是已知的,所以好办。
那么,也就是说,我们其实只需要提供我们的微信公众号的appId和secret,就能获取到access_token,从而就会获得我们需要的jsapi_ticket。
这里我们参考下github上一个示例(wechat-sdk-demo )的签名的实现。其传入的参数有两个,其中:
url: react客户端传进来的需要注入jsapi的页面url
callback: 一个回调函数,接受一个json格式的参数。主要是用来将生成的签名信息等回传给上层调用函数。
这里的流程和我们刚才描述的并无二致。首先是通过appId和secret获得调用获取jsapi_ticket的access_token,然后通过该access_token获得我们签名需要用到的jsapi_ticket。noncestr我们是提前随便填写好的。timestamp的算法也比较简单。
最后就是通过sha1这个库提供的方法,将jsapi_ticket,noncestr,timestamp和页面url进行sha1签名,然后将以上这些信息通过callback返回给上层调用函数。
那么我们往下看下我们的上层调用函数。其实就是我们的express路由:
根据微信开发文档需求,我们首先需要将传进来的url的锚点后面的数据给去掉,保留前面的有效部分。
然后就是调用上面的sign方法来生成签名。上面的签名方法最后传进来的json数据就是这里的signatureMap。我们最终会将这些数据发送回react客户端。
同时,通过上面的wx.config的示例,我们知道还需要用到微信公众号的appId。所以这里一并将其放到signatureMap中进行返回。
那么到此为止,react客户端调用服务端的"/api/signature"返回的数据示例如下:
3. 客户端获取签名信息
3.1 获取签名信息并注入jssdk
和之前的获取微信用户信息一样,我们这里会建立一个新的Source文件WechatSdkSource.js来调用远程服务器的"/api/signature"接口:
这里传进来的url由下面将要谈及的上层函数所生成。整个流程就没有什么好说的了,说白了就是通过相应的库发送一个带有url的query参数的请求到服务器端来请求签名信息,相信有跟着这个系列文章的朋友都是很清楚的了。
最终请求成功返回的时候就会调用WechatSdkActions的updateSignatureMap这个Action。
而这个action就会触发所监听的WechatSdkStore的onUpdateSignatureMap这个回调。
4. 怎么使用微信JSSDK的自定义分享功能
一,首先在公众号管理后台“公众号设置”的“功能设置”里填写JS接口安全域名,域名需要通过ICP备案,没有备案域名可以用SAE、BAE等平台。此外,自定义分享功能需要通过微信认证才能使用,没有认证的可以跟关系好的朋友借用权限,在他的JS接口安全域名设置这里填上你的域名和共享同一个开发者ID。
二,在需要调用JS接口的页面引入微信JSSDK的JS文件:http://res.wx.qq.com/open/js/jweixin-1.0.0.js,这个文件在需要分享的页面是必须要引用的,单独特别重申一下,其他方面请阅读官方文档http://mp.weixin.qq.com/wiki/7/.html
引用方法:在网页title标题下面加上:<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
三,下载官方示例代码:
http://www.huceo.com/zb_users/upload/2015/07/201507081436362390123294.zip
解压之后在例如PHP文件夹中看到以下文件:
5. 微信朋友圈JSSDK分享自定义图片文字
1、在微信公众号添加安全域名(制作的H5页面的主域名);
测试阶段,本人是通过修改hosts文件,将对应域名解析为127.0.0.1 ; 然后将电脑和手机连接至同个局域网下。修改手机代理为电脑在局域网内的IP地址;这样手机就能正常进行测试;
2、引入jssdk script src='http://res.wx.qq.com/open/js/jweixin-1.0.0.js'
3、配置jssdk,成功后方可使用相关功能,方式如下
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: 'XX', // 必填,公众号的唯一标识
timestamp: XX, // 必填,生成签名的时间戳
nonceStr: xx, // 必填,生成签名的随机串
signature: xx, // 必填,签名,见附录1
jsApiList: ['onMenuShareTimeline','onMenuShareAppMessage'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});
第一次接触时看到网上的文章在此对signature没有过多的说明,这里我自己大概说一下,此参数是通过获取公众号的id及secret获取 access _token,然后通过 access _token获取jsapi_ticket,然后通过时间戳,随机串,当前页面url,通过sha1加密生成;(这里做下说明,此步骤由后台处理后返回给前端即可);
刚接触的时候领导认为纯前端可实现,这。。。确实可以实现,这里就不做过多说明了;至于要后端处理的原因大致为两点1、公众号id和secret在前端实现不安全 2、 access _token和jsapi_ticket每日有请求次数的限制,过期时间两小时,所以需要后台在服务器缓存,每两小时获取一次;
4、wx.config配置正确即可通过wx.ready来调用相应功能
wx.ready(function() {
wx.onMenuShareTimeline({ //分享朋友圈
title: 'X', // 分享标题
link: window.location.href, // 分享链接
imgUrl: url, // 分享图标
success: function() {
// 用户确认分享后执行的回调函数
console.log('分享成功了哟哟哟')
},
cancel: function() {
// 用户取消分享后执行的回调函数
}
});
wx.onMenuShareAppMessage({ // 好友分享
title: '', // 分享标题
desc: '', // 分享描述
link: window.location.href, // 分享链接
imgUrl: '', // 分享图标
success: function () {
// 用户确认分享后执行的回调函数
},
cancel: function () {
// 用户取消分享后执行的回调函数
}
});
});
总结:其实对于前端要处理的很少,只要从后台获取signature签名,调用方法即可实现;具体可看官方文档;首次接触的小伙伴不要被吓到,就是如此简单;