周日过来撸了一下微信分享的功能,翻了以前的博客,微信分享等api笔记,发现写的真的好混乱,还有有一些点当时都写错了,顺手重新记录一遍吧。
准备工作
首先是肯定参考 微信JS-SDK说明文档,如果你还没有认证之后,开通了分享接口的微信公共号,可以在 微信公众平台
-> 开发者工具
->公共平台测试工具
,申请一个测试号。
自动分配 一个测试公众号
,AppID
,AppSecret
,这样就可以做 Token 验证和今天的主角 微信分享
了。按照 微信JS-SDK说明文档 JSSDK使用步骤,步骤一:绑定域名,在这个页面要设置 JS接口安全域名
。
注意:个人主体的公众号,是无法使用这个功能的。
另外:如果是真实的公众平台是需要验证文件的。
使用JSSDK
做完一些基础配置之后,项目中分别要做两件事情
服务端验签
获取 access_token
之后 获取 jsapi_ticket
,最后生成签名 signature
,和生成签名的参数一起返回给前端。
/**
* @var string
* APPID & APPSECRET
*/
private $APPID = "你的APPID";
private $APPSECRET = "你的APPSECRET";
/**
* @return array
* 生成签名config
*/
public function outWeixin()
{
$jsapi_ticket = $this->getJsApiTicket();
$nonceStr = 'leon0204';
$url = "https://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";//获取当前不带#和hash值的url
$timestamp = time();//当前时间戳
$string1 = "jsapi_ticket=" . $jsapi_ticket . "&noncestr=" . $nonceStr . "×tamp=" . $timestamp . "&url=" . $url;//按微信规定连接的字串
$signature = sha1($string1);//加密
$wxJsConfig = array();
$wxJsConfig['AppID'] = $this->APPID;
$wxJsConfig['timestamp'] = $timestamp;
$wxJsConfig['nonceStr'] = $nonceStr;
$wxJsConfig['signature'] = $signature;
return $wxJsConfig;
}
/**
* @return string
* 获取jsapi_ticket
*/
private function getJsApiTicket()
{
$access_token = $this->getAccessToken();
$jsapi_ticket = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" . $access_token . "&type=jsapi";
$res = file_get_contents($jsapi_ticket); //获取文件内容或获取网络请求的内容
$result = json_decode($res, true); //接受一个 JSON 格式的字符串并且把它转换为 PHP 变量
$jsapi_ticket = $result['ticket'];
return $jsapi_ticket;
}
/**
* @return mixed
* 获取access_token
*/
private function getAccessToken()
{
$token_access_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . $this->APPID . "&secret=" . $this->APPSECRET;
$res = file_get_contents($token_access_url); //获取文件内容或获取网络请求的内容
$result = json_decode($res, true); //接受一个 JSON 格式的字符串并且把它转换为 PHP 变量
$wxdata['access_token'] = $result['access_token'];
$access_token = $wxdata['access_token'];
return $access_token;
}
Important ! 这里偷懒没有写缓存 access_token
和 jsapi_ticket
,实际上一定要写的。7200S 有效期,自己随便通过什么办法设置缓存就好了,不要每次都请求接口。
页面使用 Jssdk
<script src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
<script>
//微信
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '{{$wx['AppID']}}', // 必填,公众号的唯一标识
timestamp: {{$wx['timestamp']}}, // 必填,生成签名的时间戳
nonceStr: '{{$wx['nonceStr']}}', // 必填,生成签名的随机串
signature: '{{$wx['signature']}}',// 必填,签名
jsApiList: ['onMenuShareTimeline','onMenuShareAppMessage'] // 必填,需要使用的JS接口列表
});
@foreach($articleList as $value)
@section('pageDesc')@endsection
wx.ready(function () {
wx.onMenuShareTimeline({
title: '有人邀请你看:{{$value->title}}', // 分享标题
link: window.location.href, // 分享链接
imgUrl: '', // 分享图标
success: function () {
// 用户确认分享后执行的回调函数
alert('分享成功');
},
cancel: function () {
// 用户取消分享后执行的回调函数
alert('取消分享');
}
});
wx.onMenuShareAppMessage({
title: '有人邀请你看:{{$value->title}}', // 分享标题
desc: '{{$value->description}}', // 分享描述
link: window.location.href, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: '', // 分享图标
type: '', // 分享类型,music、video或link,不填默认为link
dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
success: function () {
// 用户确认分享后执行的回调函数
alert('分享成功');
},
cancel: function () {
// 用户取消分享后执行的回调函数
alert('取消分享');
}
});
});
@endforeach
</script>
这里模版引擎是 Laravel
中的 blade
。
这样就完成分享啦
坑点
开启 debug: true
方便调试。
1 参考之前的博客,一个点造成了签名错误:
$string1 = "jsapi_ticket=".$jsapi_ticket."&noncestr=".$nonceStr."×tamp=".$timestamp."&url=".$url;//按微信规定连接的字串
// ×tamp 应该是 ×tamp ,也不知道之前是怎么记录的,坑了半天
这个签名是通过 微信 JS 接口签名校验工具 输入生成签名的参数,和微信生成的签名对比,看出来我的签名算法有问题。
2 提示 invalid url domain
,是我把域名设置成了 Https
,实际上写域名 www.xxx.com
就可以了 。
3 签名成功之后,发现分享时候,配置的标题没有生效,因为是在微信客户端测试的,后来退出微信客户端搞定。
4 如果前端用 axios
或者 ajax 调接口,可能获取不到 url
, 需要约定传递 url
参数 。axios
跨域 可以设置 header
解决 。