不使用 JSSDK 的页面,微信分享后的样子会变得很糟糕。今天来为文章页加上这个功能,以后分享内容给朋友,分享卡片也会变得美美哒。
这里需要准备一些必要的东西:
- 微信测试号(不是所有开发者都有公众号)
- 微信web开发者工具
- 域名
- 应用服务器(虚拟主机、VPS)
测试号
使用微信扫码进入测试号页面就可以拿到 appID 和 appsecret 。
测试号信息 | - |
---|---|
appID | wx7e2dbb91447* |
appsecret | 0f29148f623301adc7b2ccfd2c2* |
关注测试号
为了后续功能的开发与测试,扫描页面测试号的二维码,关注自己的测试号。
设置JS接口安全域名 misaka.im
只有该域名下的代码才能使用 JSSDK 的功能,否则会出现域名无效的错误。
后端
这里有个比较奇葩的操作,要在微信中使用 JSSDK 的功能,必须先发送浏览器当前 URL 到后端进行签名,得到 JSSDK 初始化必要的信息,才能进行初始化。
路由
使用 test.misaka.im
子域来做签名处理,使用 laravel/lumen
框架,避免与博客环境冲突。
$router->group(['prefix' => 'weixin'], function () use ($router){
$router->get('/sign', 'wxController@sign');
});
添加路由,就是前端请求获得配置参数的地址 https://test.misaka.im/weixin/sign?url=
,额外的 url
参数通过控制器函数获得。
控制器
直接使用别人写好的轮子 thenbsp/wechat,集成了微信开发的大部分功能。
namespace App\Http\Controllers;
use Doctrine\Common\Cache\FilesystemCache;
use Illuminate\Http\Request;
use Thenbsp\Wechat\Wechat\AccessToken;
use Thenbsp\Wechat\Wechat\Jsapi;
//AppSecret
const AppSecret = '0f29148f623301adc7b2ccfd2c2*****';
//AppId
const AppId = 'wx7e2dbb91447*******';
protected $cacheDriver;
/**
* wxController constructor.
*/
public function __construct()
{
$this->cacheDriver = new FilesystemCache('../cache');
}
public function sign(Request $request)
{
$accessToken = new AccessToken(static::AppId, static::AppSecret);
if (!$accessToken->getTokenString()) {
$accessToken->setCache($this->cacheDriver);
}
$jsapi = new Jsapi($accessToken);
$jsapi->setCache($this->cacheDriver);
if ($request->has('url')) {
$jsapi->setCurrentUrl($request->get('url'));
}
if ($request->has('apis')) {
foreach (explode(',', $request->get('apis')) as $api) {
try {
$jsapi->addApi($api);
} catch (\Exception $e) {
return response($e->getMessage(), 400);
}
}
}
return response(['data' => $jsapi->getConfig(true)])->header('Access-Control-Allow-Origin', '*');
}
逻辑代码中填写测试号的 AppSecret 和 AppId 。通过获取 url
参数来签名,返回 JSSDK 所需的初始化参数。
因为前端请求域名不是主站,存在跨域问题,另外返回了允许跨域的 HTTP header。
响应结果
浏览器访问 https://test.misaka.im/weixin/sign?url=https%3A%2F%2Fmisaka.im%2Findex.php%2Farchives%2F41%2F
可以测试签名结果:
{
"data": {
"appId" : "wx7e2dbb91447*****",
"nonceStr" : "vFMyHt6OoE",
"timestamp": "1544497646",
"signature": "bc29b6bbffea958f1928bbf083828f4bf87cace8",
"jsApiList": [],
"debug" : false
}
}
前端
官方 demo 使用了后端渲染的页面直接获取当前浏览器的 URL ,当多数情况是通过接口方式获取前端的:
encodeURIComponent(window.location.href)
如果前端使用 Vue 这些 SPA 框架时,这个情况变得更加复杂:
同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化(路由)时进行调用
引入 JSSDK
在主题模板 header.php 中引入
<script src="//res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
初始化
Typecho 中使用了 jQuery 1.9 ,直接使用 jQuery Ajax 来发起请求。
在模板 footer.php
中加入:
var desc = "一眨眼一年,我的钱呢?";
var share_title = $(".content > h1").text();
var share_icon = 'http://ww1.sinaimg.cn/large/8b2a5a08gy1fy1s3tn6j8j203u03saa0.jpg';
var share_link = window.location.href.split("#")[0].split("?")[0];
$.getJSON('//test.misaka.im/weixin/sign?url=' + encodeURIComponent(window.location.href), function (res) {
console.log(res)
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: res.data.appId, // 必填,企业号的唯一标识,此处填写企业号corpid
timestamp: res.data.timestamp, // 必填,生成签名的时间戳
nonceStr: res.data.nonceStr, // 必填,生成签名的随机串
signature: res.data.signature, // 必填,签名,见附录1
jsApiList: [
'onMenuShareTimeline', // 分享给好友
'onMenuShareAppMessage', // 分享到朋友圈
'onMenuShareQQ', // 分享到QQ
] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
})
wx.ready(function () {
wx.onMenuShareTimeline({ // 例如分享到朋友圈的API
title: share_title, // 分享标题
link: location.href, // 分享链接
imgUrl: share_icon, // 分享图标
success: function () {},
cancel: function () {}
})
wx.onMenuShareAppMessage({
title: share_title, // 分享标题
desc: desc, // 分享描述
link: location.href, // 分享链接
imgUrl: share_icon, // 分享图标
type: '', // 分享类型,music、video或link,不填默认为link
dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
success: function () {},
cancel: function () {}
})
wx.onMenuShareQQ({
title: share_title, // 分享标题
desc: desc, // 分享描述
link: location.href, // 分享链接
imgUrl: share_icon, // 分享图标
success: function () {},
cancel: function () {}
})
})
wx.error(function (res) {
console.log(res.errMsg); // 打印错误消息。及把 debug:false,设置为debug:ture就可以直接在网页上看到弹出的错误提示
})
})
使用开发者工具调试
鉴于国内的特殊情况,微信成了独立的一种生态环境,针对它形成的产品场景也不少。使用微信web开发者工具 来调试应用,这样就不用每次提交代码到线上再用手机测试啦。
微信web开发者工具
使用公众号网页调试,开发者可以调试微信网页授权和微信JS-SDK
打开这个工具之后提示使用微信扫码登录,有确认登录界面,并显示了你拥有哪些公众号开发者权限
看界面就是套了个 Chromium,聚合了微信大部分 SDK 功能,模拟 SDK 输入和输出。
访问文章页
修改了模板文件 header.php
和 footer.php
,来测试下效果。调试工具直接访问 https://misaka.im/index.php/archives/41/
页面加载完后,会发出一条 XHR 请求,url 参数是 urlencode 之后的当前地址
点击展开详细面板
当 JSSDK 初始化完成后会在 Console 调试台中打印出相关信息
wx.config begin
表示 wx.config() 被调用,及传入的参数wx.config end
表示 JSSDK 初始化完成, errMsg:ok 代表初始成功- 可用的操作权限列表
模拟分享操作
点击右上角更多的操作,点击发送给朋友或朋友圈
分享前后, Console 调试台会打印出分享的具体信息:
wx.onMenuShareAppMessage begin
触发 onMenuShareAppMessage() 配置好的分享信息wx.onMenuShareAppMessage end
触发 onMenuShareAppMessage() 配置好的分享回调
DEMO
使用微信web开发者工具打开 前端 demo(http://203.195.235.76/jssdk/), 右侧调试面板显示了代码是如何运作的。