MENU

Vue.js实现微信分享功能

前言

年前做的四六级准考证查询,想着分享链接出来的时候逼格高一点,所以就动手实现该微信分享功能,怎么说,微信分享不算是新的知识点吧,因为去年微信公众号的时候有接触,所以对于后端这里是没有什么毛病,但是前端Vue框架hash模式确实比较坑(怎么坑法?接下来慢慢细说哈!)。

实现方法

这里就先把后端代码贴出来哈,按照官方文档敲出来的,其实很简单。(后端依旧用的是laravel框架),返回是采用接口的方式返回

   /**
    * 请求接口方法
    */
    public function curl($url, $type = 'get', $data = '')
    {
        
        //Curl处理
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($curl, CURLOPT_HEADER, 0);
        curl_setopt($curl, CURLOPT_TIMEOUT, 30);
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
        if ($type = 'post') {
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        }
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $result = curl_exec($curl);
        curl_close($curl);
        return $result;
    }
    /**
     * @return \Illuminate\Session\SessionManager|\Illuminate\Session\Store|mixed
     * 获取全局access_token票据
     */
    public function GetAccessToken()
    {
        $appid = '你微信公众号的appID';
        $secret = '你微信公众号的appSecret';

        //如果access_token没有过期,直接return
        if (session('access_token') && session('expire_time') > time()) {
            return session('access_token');
        } else {
            //重新获取access_token
            $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' . $appid . '&secret=' . $secret;
            $res = $this->curl($url, 'get', 'json');
            $res = json_decode($res, true);
            session(['access_token' => $res['access_token']]);
            session(['expire_time' => (time() + 7000)]);
            return session('access_token');
        }
    }

    /**
     * @return mixed
     * 获取JsTicket
     */
    public function GetJsTicket()
    {
        if (!session('JsTicket') && session('JsExpire_time') < time()) {
            $Access_Token = $this->GetAccessToken();
            $url = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=' . $Access_Token . '&type=jsapi';
            $res = $this->curl($url, 'get', 'json');
            $res = json_decode($res, true);
            session(['JsTicket' => $res['ticket']]);
            session(['JsExpire_time' => (time() + 7000)]);
            return $res['ticket'];
        } else {
            return session('JsTicket');
        }

    }


    /**
     * @param int $length
     * @return string
     * 获取16位随机数
     */
    public function GetNoncestr($length = 16)
    {
        $str = "1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM";
        $res = "";
        for ($i = 0; $i < $length; $i++) {
            $res .= substr($str, mt_rand(0, strlen($str) - 1), 1);
        }
        return $res;
    }

    /**
     * @return \Illuminate\Http\JsonResponse
     * Signature签名接口  返回前端
     */
    public function RspSignature()
    {
        $data = Input::all();
        if (empty($data['PostUrl'])) {
            return response()
                ->json([
                    'status' => 403,
                    'msg' => '请输入URL链接!'
                ]);
        } else {
            $noncestr = $this->GetNoncestr();
            $jsapi_ticket = $this->GetJsTicket();
            $timestamp = time();
            $url = $data['PostUrl'];
            $str = 'jsapi_ticket=' . $jsapi_ticket . '&noncestr=' . $noncestr . '&timestamp=' . $timestamp . '&url=' . $url;
            return response()
                ->json([
                    'status' => 200,
                    'msg' => [
                        'appId' => config('app.appID'),
                        'timestamp' => $timestamp,
                        'nonceStr' => $noncestr,
                        'signature' => sha1($str),
                    ]
                ]);
        }
    }

重点

上面是后端代码,但是本次的重点是前端Vue框架的
Vue框架中路由默认hash模式,怎么是hash模式?看下面的说明

正常访问链接(也即是下面要介绍的history模式):  https://cet.icharle.com/ticket
hash模式链接: https://cet.icharle.com/#/ticket

我个人认为hash模式用是简单,但是链接对于SEO不友好,而且对于做微信分享的时候,会将#后面的参数去掉,这样就会出现无法分享指定页面到朋友圈。所以,个人认为还是采用history模式。一开始,博主也在这里入坑了,最后查官网发现居然还有history模式。

具体实现方法:原理监听路由切换,然后请求后台接口重新签名,最后返回前台。

router.afterEach((to, from) => {
    let _url = window.location.origin + to.fullPath
    axios({
        url: '请求后台签名接口链接',
        method: 'post',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        params: {
            PostUrl: _url
        },
        dataType: 'json',
    }).then(response => {
        let data = response.data.msg
        wx.config({
            debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
            appId: data.appId, // 必填,公众号的唯一标识
            timestamp: data.timestamp, // 必填,生成签名的时间戳
            nonceStr: data.nonceStr, // 必填,生成签名的随机串
            signature: data.signature,// 必填,签名
            jsApiList: ['onMenuShareTimeline', 'onMenuShareAppMessage'] // 必填,需要使用的JS接口列表
        });
        //下面是相关配置,自己可以按照需要修改配置
        wx.ready(() => {
            wx.onMenuShareTimeline({
                title: '四六级准考证查询', // 分享标题
                link: _url,
                imgUrl: 'https://icharle.com/logo/logo.png', // 分享图标
                success: function () {
                    // 用户确认分享后执行的回调函数
                }, cancel: function () {
                    // 用户取消分享后执行的回调函数
                }
            });
            wx.onMenuShareAppMessage({
                title: '四六级准考证查询', // 分享标题
                desc: '四六级免证查询', // 分享描述
                link: _url,
                imgUrl: 'https://icharle.com/logo/logo.png', // 分享图标
                type: '', // 分享类型,music、video或link,不填默认为link
                dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
                success: function () {
                    // 用户确认分享后执行的回调函数
                },
                cancel: function () {
                    // 用户取消分享后执行的回调函数
                }
            });
        });
        wx.error(function (res) {

        });
    })
        .catch(function (error) {
            console.log(error);
        });
})
标签: vue.js, 前端
返回文章列表 文章二维码 打赏
本页链接的二维码
打赏二维码