10

为 Typecho 文章页加入微信分享功能

 3 years ago
source link: http://misaka.im/index.php/archives/27/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

为 Typecho 文章页加入微信分享功能

2018.09.03默认分类 0 评
a4cae12c77245144.jpg

不使用 JSSDK 的页面,微信分享后的样子会变得很糟糕。今天来为文章页加上这个功能,以后分享内容给朋友,分享卡片也会变得美美哒。

这里需要准备一些必要的东西:

使用微信扫码进入测试号页面就可以拿到 appIDappsecret

测试号信息-appIDwx7e2dbb91447*appsecret0f29148f623301adc7b2ccfd2c2*
关注测试号

为了后续功能的开发与测试,扫描页面测试号的二维码,关注自己的测试号。

c1d571201eb6a986.png
设置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', '*');
}

逻辑代码中填写测试号的 AppSecretAppId 。通过获取 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

打开这个工具之后提示使用微信扫码登录,有确认登录界面,并显示了你拥有哪些公众号开发者权限

28bc653ffe9511de.jpg

看界面就是套了个 Chromium,聚合了微信大部分 SDK 功能,模拟 SDK 输入和输出。

访问文章页

修改了模板文件 header.phpfooter.php ,来测试下效果。调试工具直接访问 https://misaka.im/index.php/archives/41/

a5b06a158fa1d165.jpg

页面加载完后,会发出一条 XHR 请求,url 参数是 urlencode 之后的当前地址

060c0832cdde53d0.jpg

点击展开详细面板

4bc6b63f4aa6d1bf.jpg

当 JSSDK 初始化完成后会在 Console 调试台中打印出相关信息

  • wx.config begin 表示 wx.config() 被调用,及传入的参数
  • wx.config end 表示 JSSDK 初始化完成, errMsg:ok 代表初始成功
  • 可用的操作权限列表
模拟分享操作
52f48f09c5981ea2.jpg

点击右上角更多的操作,点击发送给朋友或朋友圈

499fc55829b88abb.jpg

分享前后, Console 调试台会打印出分享的具体信息:

  • wx.onMenuShareAppMessage begin 触发 onMenuShareAppMessage() 配置好的分享信息
  • wx.onMenuShareAppMessage end 触发 onMenuShareAppMessage() 配置好的分享回调

使用微信web开发者工具打开 前端 demohttp://203.195.235.76/jssdk/), 右侧调试面板显示了代码是如何运作的。

0a15768a7355d19f.png

至于签名的一些逻辑操作,官方那个给出了签名的正确姿势前端 demo


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK