一、h5二次分享后,摘要和图片丢失
标题被截短,描述也变成了链接,图片也没有,运营人员半夜还在嚷嚷,无奈只好硬着头皮去百度,去google,但是悲催的是没有详细的解决方法,最终只能自己去研究,还好最终搞出来了,决定分享一下,帮助需要的人。
二、网上的坑
刚开始在网上找了些资料,说在body下面增加一个图片,隐藏起来就可以了,微信会默认选取网页中第一张图片作为小图标,试了几次发现不行呀,分享到QQ中倒是这个逻辑,估计是很早之前的逻辑吧。
三、解决方案
1.首先配置js接口安全域
在公众号的功能设置-JS接口安全域名里面绑定自己分享网页的域名,
完了之后在页面引入微信的js文件:http://res.wx.qq.com/open/js/jweixin-1.2.0.js
进行认证操作,代码如下:
wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '', // 必填,公众号的唯一标识
timestamp: , // 必填,生成签名的时间戳
nonceStr: '', // 必填,生成签名的随机串
signature: '',// 必填,签名
jsApiList: [] // 必填,需要使用的JS接口列表
});
而这些值怎么来呢,从服务端的接口获取
2.服务端接口逻辑
public function action() {
$config = (new \Dao\Db\Applet\Common\Openid())->getConfigInfo();
$ticket = $this->getTicket($config);
$url = 'https://proof.hn-qingjin.com/';
if ($this->params['wechaturl']) {
$url = $this->params['wechaturl'];
}
$ret['timestamp'] = (string)time();
$ret['noncestr'] = \S\Util\Rand::human(16);
$ret['jsapi_ticket'] = $ticket;
$ret['url'] = $url;
$ret['signature'] = $this->getSign($ret);
$ret['appid'] = $config['appid'];
$this->response['data'] = $ret;
}
getConfigInfo是获取配置,里面返回appid和secret
protected function getTicket($config) {
$biz = new \Dao\Db\Applet\Common\Ticket();
$one = $biz->getOne(['appid' => $config['appid']]);
if ($one) {
if ($one['expires'] > time()) {
return $one['ticket'];
} else {
$url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$config['appid'].'&secret='.$config['secret'];
$curl = new \S\Util\Curl($url);
$ret = $curl->get();
$ret = json_decode($ret, true);
$data = [];
$query['appid'] = $config['appid'];
$data['accessToken'] = $ret['access_token'];
$data['ticket'] = $this->getTicketInfo($data['accessToken'], $config);
$data['expires'] = time()+7000;
$biz->update($query, $data);
return $data['ticket'];
}
} else {
$url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$config['appid'].'&secret='.$config['secret'];
$curl = new \S\Util\Curl($url);
$ret = $curl->get();
$ret = json_decode($ret, true);
$data['accessToken'] = $ret['access_token'];
if (!$data['accessToken']) {
throw new Exception('token生成失败');
}
$data['ticket'] = $this->getTicketInfo($data['accessToken'], $config);
$data['expires'] = time()+7000;
$data['appid'] = $config['appid'];
$biz->add($data);
return $data['ticket'];
}
}
getTicket函数是获取token和ticket信息,并保存数据库。jsapi_ticket是公众号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务
protected function getTicketInfo($token, $config) {
$url = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token='.$token.'&type=jsapi';
$curl = new \S\Util\Curl($url);
$ret = $curl->get();
$ret = json_decode($ret, true);
return $ret['ticket'];
}
getTicketInfo通过token获取ticket
protected function getSign($ret) {
$biz = new Dao\Db\Applet\Common\Sign();
return $biz->getSign($ret);
}
getSign是进行加密,以下是Dao里面的逻辑
public function getSign($param) {
ksort($param);
foreach ($param as $key=>$value){
$str .= $key.'='.$value.'&';
}
return sha1(trim($str, '&'));
}
四、特别注意的是link: location.href
1.花费时间最多的就是在这边,图标一直出不来的原因是这边的地址需要和后台签名的地址一模一样,之前我也是通过固定的地址加参数拼的,比如:http://cxytiandi.com/article/文章ID这样去弄的,上面也说过了,微信会再后面追加参数,导致了两边不一致,所以这边直接用location.href就可以了。
2.如果报错invalid ip 222.128.31.228 ipv6 ::ffff:222.128.31.228, not in whitelist rid: 5fb61946-2d7f6c4f-457f4818此类
请在微信公众号后台,配置获取token的IP白名单。