0

    Php网页分享到微信朋友圈带摘要和缩略图

    2023.05.07 | admin | 145次围观

    最近弄了几个单独的落地页,需要分享到微信,新版的微信规则是很早就变了。

    要是想分享出去的页面带摘要,缩略图(重点),得把域名找个认证的公众号加进去以及网站的服务器ip。

    前提:

    1:认证微信公众号

    2:当前网站域名加进公众号的js安全域名中

    3:当前网站服务器的ip加进公众号的ip白名单中

    如果没有,那我也不知道,没测试过别的。

    官方说明:微信JS-SDK说明文档二:写好JS-SDK文档文件

    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代码是在网上搜索出来,改了下的,我大概看了下,有很多写法html页面分享到朋友圈,当然本质都是一样的。

    三:网页需要加的代码:

    GetSignPackage();  
    $data = array(
     'appId' => $signPackage["appId"], 
     'nonceStr' => $signPackage["nonceStr"],
     'timestamp' => $signPackage["timestamp"],
     'signature' => $signPackage["signature"]);
    ?>
    
    

    尽量把代码加到需要分享页面的头部。

    查看网页源码,可以看见上面这一段,但是php这段看不见,只不过会把公众号的appid显示出来,其他都是随机变的。

    如果不想显示这段信息出来,可以把里面的混淆了或者加密隐藏。

    本来想写成wordpress插件的,结果看网上已经有想过插件了html页面分享到朋友圈,功能还更强大一些,就懒得动了。

    是用wordpress的,不想自己动手就直接在后台搜索安装插件吧。

    版权声明

    本文仅代表作者观点。
    本文系作者授权发表,未经许可,不得转载。

    发表评论