php后台部分-微信类
/*********微信自定义分享 开始********/ /** * 获取微信自定已分享配置参数包 * @author ganyuanjiang <3164145970@qq.com> * @createtime 2017-08-05 14:21:04 * @return array 配置参数包 */ public function getSignPackage() { $jsapiTicket = $this->getJsApiTicket(); // 注意 URL 一定要动态获取,不能 hardcode. $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://"; $url = "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"; $timestamp = time(); $nonceStr = $this->createNonceStr(); // 这里参数的顺序要按照 key 值 ASCII 码升序排序 $string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr×tamp=$timestamp&url=$url"; $signature = sha1($string); $signPackage = array( "appId" => $this->appid, "nonceStr" => $nonceStr, "timestamp" => $timestamp, "url" => $url, "signature" => $signature, "rawString" => $string ); return $signPackage; } /** * 微信自定义分享随机字符串 * @author ganyuanjiang <3164145970@qq.com> * @createtime 2017-08-05 14:22:15 * @param length int 随机字符串长度 * @return str string 随机字符串 */ private function createNonceStr($length = 16) { $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; $str = ""; for ($i = 0; $i < $length; $i++) { $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); } return $str; } /** * 微信自定义分享获取jsapiticket * @author ganyuanjiang <3164145970@qq.com> * @createtime 2017-08-05 14:23:30 * @return jsapi_ticket string 微信jsapi调用凭证 */ private function getJsApiTicket() { // jsapi_ticket 应该全局存储与更新,以下代码以写入到文件中做示例 $data = json_decode(file_get_contents("jsapi_ticket.json")); if ($data->expire_time < time()) { $access_token = $this->access_token(false); // 如果是企业号用以下 URL 获取 ticket // $url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=".$access_token['data']; $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=".$access_token['data']; $res = json_decode(https_get($url)); $ticket = $res->ticket; if ($ticket) { $data->expire_time = time() + 7200; $data->jsapi_ticket = $ticket; $fp = fopen("jsapi_ticket.json", "w"); fwrite($fp, json_encode($data)); fclose($fp); } } else { $ticket = $data->jsapi_ticket; } return $ticket; } /*********微信自定义分享 结束********/
php后台部分-控制器
use utilWeChat as WeChatModel; use appadminmodelAttachment as AttachmentModel; use appcrmmodelHelp as HelpModel; /** * 初始化方法 * @author ganyuanjiang <3164145970@qq.com> * @time 2017-07-26 11:04:56 * */ protected function _initialize() { $this->WeChat = new WeChatModel(); //微信统一分享 $this->shareInfo(); } /** * 客分享注册信息 * @author ganyuanjiang <3164145970@qq.com> * @createtime 2017-07-29 13:28:35 */ private function shareInfo(){ //查询推荐规则介绍 $map['key'] = 'share_intro'; $share_intro = HelpModel::where($map)->find(); if(!$share_intro){ return $this->error("分享规则介绍不存在"); } //通过图片编号查询图片地址 $map_img['id'] = $share_intro['image']; $path = AttachmentModel::where($map_img)->value('path'); $share_intro['image'] = empty($path)?'':$this->request->domain().PUBLIC_PATH.$path; //分享页 $share_intro['url'] = $this->request->root(true).'/'.$this->request->module().'/publics/welcome.html'; //微信分享自定义参数 $signPackage = $this->WeChat->getSignPackage(); $signPackage['redirect_uri'] = urlencode(config('crm_config.user_accesstoken_uri')); $signPackage['encrypt_key'] = config('crm_config.encrypt_key'); //模板渲染 $this->assign('signPackage',$signPackage); $this->assign('share_intro',$share_intro);//分享规则介绍 }
html页面部分
首先引入微信js文件
<script src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script> <script type="text/javascript"> var uid= $.cookie("uid") == "undefined"?0:$.cookie("uid"); /**分享信息初始化 开始**/ if(uid!=undefined && uid!=0){ wx.config({ debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId: '{$signPackage.appId}', // 必填,公众号的唯一标识 timestamp: {$signPackage.timestamp}, // 必填,生成签名的时间戳 nonceStr: '{$signPackage.nonceStr}', // 必填,生成签名的随机串 signature: '{$signPackage.signature}',// 必填,签名,见附录1 jsApiList: [ 'checkJsApi', //判断当前客户端版本是否支持指定JS接口 'onMenuShareTimeline', //分享给好友 'onMenuShareAppMessage', //分享到朋友圈 'onMenuShareQQ', //分享到QQ 'onMenuShareQZone', //分享到QQ ] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); //处理成功验证 wx.ready(function(){ //处理失败验证 wx.error(function(res){ alert(res.errMsg); //打印错误消息。及把 debug:false,设置为debug:ture就可以直接在网页上看到弹出的错误提示 }); //获取“分享到朋友圈”按钮点击状态及自定义分享内容接口 wx.onMenuShareTimeline({ title: '{$share_intro.name}', // 分享标题 link: '{$share_intro.url}?state='+uid, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致 // imgUrl: '{$share_intro.image}', // 分享图标 trigger: function (res) { // 不要尝试在trigger中使用ajax异步请求修改本次分享的内容,因为客户端分享操作是一个同步操作,这时候使用ajax的回包会还没有返回. //alert('click shared'); }, success: function () { // 用户确认分享后执行的回调函数 }, cancel: function () { // 用户取消分享后执行的回调函数 },fail: function (res) { //alert(JSON.stringify(res)); } }); //获取“分享给朋友”按钮点击状态及自定义分享内容接口 wx.onMenuShareAppMessage({ title: '{$share_intro.name}', // 分享标题 desc: '{$share_intro.intro}', // 分享描述 link: '{$share_intro.url}?state='+uid, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致 imgUrl: '{$share_intro.image}', // 分享图标 type: '', // 分享类型,music、video或link,不填默认为link dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空 success: function () { // 用户确认分享后执行的回调函数 }, cancel: function () { // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ”按钮点击状态及自定义分享内容接口 wx.onMenuShareQQ({ title: '{$share_intro.name}', // 分享标题 desc: '{$share_intro.intro}', // 分享描述 link: '{$share_intro.url}?state='+uid, // 分享链接 imgUrl: '{$share_intro.image}', // 分享图标 success: function () { // 用户确认分享后执行的回调函数 }, cancel: function () { // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ空间”按钮点击状态及自定义分享内容接口 wx.onMenuShareQZone({ title: '{$share_intro.name}', // 分享标题 desc: '{$share_intro.intro}', // 分享描述 link: '{$share_intro.url}?state='+uid, // 分享链接 imgUrl: '{$share_intro.image}', // 分享图标 success: function () { // 用户确认分享后执行的回调函数 }, cancel: function () { // 用户取消分享后执行的回调函数 } }); wx.error(function (res) { alert(res.errMsg); }); }); } /**分享信息初始化 结束**/ </script>
注意:另外说明一点微信分享的链接的域名必须与js安全域名一致 不能将微信授权或其它域名当做分享链接,若这样做微信内分享到朋友圈和分享到朋友无法读取自定义内容 仅qq和qq空间可以读取
解决办法 定义一个中转链接,此链接在js安全域名下 或者自定义一个js安全域名下的页面 然后跳转到授权链接