最近弄了几个单独的落地页,需要分享到微信,新版的微信规则是很早就变了。
要是想分享出去的页面带摘要,缩略图(重点),得把域名找个认证的公众号加进去以及网站的服务器ip。
前提:
1:认证微信公众号
2:当前网站域名加进公众号的js安全域名中
3:当前网站服务器的ip加进公众号的ip白名单中
如果没有,那我也不知道,没测试过别的。
官方说明:
微信JS-SDK说明文档
二:写好JS-SDK文档文件
<?php /** * description: 微信页面授权 */ class JSSDK{ private $appId; private $appSecret; public function __construct($appId, $appSecret) { $this->appId = $appId; $this->appSecret = $appSecret; } /* * 获取access_token * (需要缓存,可利用数据库存储,不要频繁刷新获取) * http请求方式: GET https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET * 接口请求参数 * 参数 是否必须 说明 grant_type 是 获取access_token填写client_credential appid 是 第三方用户唯一凭证 secret 是 第三方用户唯一凭证密钥,即appsecret * 接口返回说明 * {"access_token":"ACCESS_TOKEN","expires_in":7200} access_token 获取到的凭证 expires_in 凭证有效时间,单位:秒 * 接口错误说明 * {"errcode":40013,"errmsg":"invalid appid"} * */ private function getAccessToken(){ $appId = $this->appId; $appSecret = $this->appSecret; $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$this->appId&secret=$this->appSecret"; $res = $this->api_request($url); if(isset($res->access_token)){ return array( 'errcode' =>0, 'errmsg' =>'success', 'access_token' =>$res->access_token, 'expires_in' =>$res->expires_in ); }else{ return array( 'errcode' =>$res->errcode, 'errmsg' =>$res->errmsg, 'access_token' =>null, 'expires_in' =>null ); } } /* * 获取jsapi_ticket * (有效期7200秒,开发者必须在自己的服务全局缓存jsapi_ticket) * 请求方式:https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi * 接口返回值:JSON * { "errcode":0, "errmsg":"ok", "ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA", "expires_in":7200 } * */ private function getJsApiTicket(){ $access_token_data = $this->getAccessToken(); if($access_token_data['errcode']==0){ $access_token = $access_token_data['access_token']; $url = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token='.$access_token.'&type=jsapi'; //$url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=$accessToken"; $res = $this->api_request($url); if($res->errcode==0){ return array( 'errcode' =>$res->errcode, 'errmsg' =>$res->errmsg, 'ticket' =>$res->ticket, 'expires_in' =>$res->expires_in ); }else{ return array( 'errcode' =>$res->errcode, 'errmsg' =>$res->errmsg, 'ticket' =>null, 'expires_in' =>null ); } }else{ return array( 'errcode' =>$access_token_data['errcode'], 'errmsg' =>$access_token_data['errmsg'], 'ticket' =>null, 'expires_in' =>null ); } } /* * 签名算法 * 签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。 * 1、对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后, * 2、使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。 * 这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。 * */ /* * 获取随机字符串 * mt_rand() 使用 Mersenne Twister 算法返回随机整数。 * mt_rand(min,max)如果没有提供可选参数 min 和 max,mt_rand() 返回 0 到 RAND_MAX 之间的伪随机数。 * 想要 5 到 15(包括 5 和 15)之间的随机数,用 mt_rand(5, 15)。 * 此函数rand()快四倍 * */ /* * 1.签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同。 * 2.签名用的url必须是调用JS接口页面的完整URL。 * 3.出于安全考虑,开发者必须在服务器端实现签名的逻辑。 * 注意: * 确保你获取用来签名的url是动态获取的,动态页面可参见实例代码中php的实现方式。 * 如果是html的静态页面在前端通过ajax将url传到后台签名,前端需要用js获取当前页面除去'#'hash部分的链接(可用location.href.split('#')[0]获取,而且需要encodeURIComponent), * 因为页面一旦分享,微信客户端会在你的链接末尾加入其它参数,如果不是动态获取当前链接,将导致分享后的页面签名失败。 * */ public function getSignPackage() { $jsapiTicket_data = $this->getJsApiTicket(); $url = $this->getUrl(); $timestamp = time(); $nonceStr = $this->getNonceStr(); if($jsapiTicket_data['errcode']==0){ $jsapiTicket = $jsapiTicket_data['ticket']; // 这里参数的顺序要按照 key 值 ASCII 码升序排序 $string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr×tamp=$timestamp&url=$url"; $signature = sha1($string); return array( "appId" => $this->appId, "nonceStr" => $nonceStr, "timestamp" => $timestamp, "url" => $url, "signature" => $signature, "rawString" => $string, "errcode" => $jsapiTicket_data['errcode'], "errmsg" => $jsapiTicket_data['errmsg'] ); }else{ return array( "appId" => $this->appId, "nonceStr" => $nonceStr, "timestamp" => $timestamp, "url" => $url, "signature" => null, "rawString" => null, "errcode" => $jsapiTicket_data['errcode'], "errmsg" => $jsapiTicket_data['errmsg'] ); } } /* * 获取nonceStr * */ private function getNonceStr($length = 16) { $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; $nonceStr = ""; for ($i = 0; $i < $length; $i++) { $nonceStr .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); } return $nonceStr; } /* * 获取url * url(当前网页的URL,不包含#及其后面部分) * */ private function getUrl(){ $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://"; $url = "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"; return $url; } /* * 微信API调用方法 * */ private function api_request($url,$data=null){ //初始化cURL方法 $ch = curl_init(); //设置cURL参数(基本参数) $opts = array( //在局域网内访问https站点时需要设置以下两项,关闭ssl验证! //此两项正式上线时需要更改(不检查和验证认证) CURLOPT_SSL_VERIFYPEER => false, CURLOPT_SSL_VERIFYHOST => false, CURLOPT_TIMEOUT => 500, CURLOPT_RETURNTRANSFER => true, CURLOPT_URL => $url, ); curl_setopt_array($ch, $opts); //post请求参数 if (!empty($data)) { curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); } //执行cURL操作 $output = curl_exec($ch); if (curl_errno($ch)) { //cURL操作发生错误处理。 var_dump(curl_error($ch)); die; } //关闭cURL curl_close($ch); $res = json_decode($output); return ($res); //返回json数据 } }
这个JSSDK.php代码是在网上搜索出来,改了下的,我大概看了下,有很多写法,当然本质都是一样的。
三:网页需要加的代码:
<?php require_once "jssdk.php";//引入相应路径下的jssdk文件 $jssdk = new JSSDK("appid","公众号密钥");//按照自己的公众号填写 $signPackage = $jssdk->GetSignPackage(); $data = array( 'appId' => $signPackage["appId"], 'nonceStr' => $signPackage["nonceStr"], 'timestamp' => $signPackage["timestamp"], 'signature' => $signPackage["signature"]); ?> <script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script> <script> var url=window.location.href; wx.config({ debug:false, appId: '<?php echo $data["appId"];?>', timestamp: <?php echo $data["timestamp"];?>, nonceStr: '<?php echo $data["nonceStr"];?>', signature: '<?php echo $data["signature"];?>', url:url, jsApiList: [ "onMenuShareTimeline", //分享给好友 "onMenuShareAppMessage", //分享到朋友圈 "onMenuShareQQ", //分享到QQ "onMenuShareWeibo" //分享到微博 ] }); wx.ready(function (){ var shareData = { title: '分享出去的标题', desc: '分享出去的摘要', link: url, imgUrl: '分享出去的缩略图'}; //最好是300x300以上的正方形 wx.onMenuShareAppMessage(shareData); wx.onMenuShareTimeline(shareData); wx.onMenuShareQQ(shareData); wx.onMenuShareWeibo(shareData); }); </script>
尽量把代码加到需要分享页面的头部。
查看网页源码,可以看见上面这一段,但是php这段看不见,只不过会把公众号的appid显示出来,其他都是随机变的。
如果不想显示这段信息出来,可以把<script></script>里面的混淆了或者加密隐藏。
本来想写成wordpress插件的,结果看网上已经有想过插件了,功能还更强大一些,就懒得动了。
是用wordpress的,不想自己动手就直接在后台搜索安装插件吧。