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 . '×tamp=' . $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);
});
})