实现H5连接分享给好友或朋友圈自定义分享内容(标题、图片、简介)的方法代码

实现H5连接分享给好友或朋友圈自定义分享内容方法

    • 首先配置公众号
      • JS接口安全域名
      • 设置ip白名单
    • 其次配置接口
      • 配置JSSDK
    • 最后html分享页面联调
    • 常见错误
      • invalid credential, access_token is invalid or not latest hint

首先配置公众号

JS接口安全域名

接入jssdk时,就需要配置JS接口安全域名,因此需要登录微信公众平台,在公众号设置→功能设置中,填写JS接口安全域名,域名即为H5项目的域名(如:www.baidu.com),同时需要下载一个txt验证文件,并放置到服务器的根路径下,实际操作时根据提示即可。

实现H5连接分享给好友或朋友圈自定义分享内容(标题、图片、简介)的方法代码_第1张图片

设置ip白名单

这一步其实应该放到后面获取access_token步骤中,我这里正好已经登录在公众号平台,所以就一并操作了。后面讲到获取access_token和jsapi_ticket时,需要访问服务器,因此需要将H5项目服务器的IP地址添加到白名单中,否则接口将无法调用成功。具体设置方法:在开发→基本设置→IP白名单中进行添加相应的IP地址即可。如下图所示

在这里插入图片描述

其次配置接口

我用的是yii2框架

<?php

//引用JSSDK
use app\weixinapi\wxconfigs\JSSDK;

//请求当前接口的网址路径
$post_url=$post['url'];
 //配置的公众号或订阅号的AppID和AppSecret 设置成自己的
$jssdk = new JSSDK("AppID", "AppSecret");
$signPackage = $jssdk->GetSignPackage($post_url);
$data['signPackage'] = $signPackage;
$result=array('status' => 0, 'msg' => 'success!', 'data' => [$data])

return $result;

配置JSSDK


<?php

namespace app\weixinapi\wxconfigs;

class JSSDK
{
     
    private $appId;
    private $appSecret;

    public function __construct($appId, $appSecret)
    {
     
        $this->appId = $appId;
        $this->appSecret = $appSecret;
    }

    public function getSignPackage($post_url)
    {
     
        $jsapiTicket = $this->getJsApiTicket();
        $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
        // $url = "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
        $url = $post_url;


        $timestamp = time();
        $nonceStr = $this->createNonceStr();

        // 这里参数的顺序要按照 key 值 ASCII 码升序排序
        $string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr×tamp=$timestamp&url=$url";
        log::writeLog('getSignPackage的$string===' . $string);
        $signature = sha1($string);

        $signPackage = array(
            "appId" => $this->appId,
            "nonceStr" => $nonceStr,
            "timestamp" => $timestamp,
            "url" => $url,
            "signature" => $signature,
            "rawString" => $string
        );
        return $signPackage;
    }

    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;
    }

    private function getJsApiTicket()
    {
     
        // jsapi_ticket 应该全局存储与更新,以下代码以写入到文件中做示例
        $data = json_decode(file_get_contents(Yii::$app->basePath . "/weixinapi/wxconfigs/jsapi_ticket.json"));
        if ($data->expire_time < time()) {
     
            $accessToken = $this->getAccessToken();
            // 如果是企业号用以下 URL 获取 ticket
            // $url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=$accessToken";
            $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=$accessToken";
            log::writeLog('getJsApiTicket的$url===' . $url);
            $res = json_decode($this->httpGet($url));
            $ticket = $res->ticket;
            log::writeLog('$ticket===' . $ticket);
            if ($ticket) {
     
                $data->expire_time = time() + 7000;
                $data->jsapi_ticket = $ticket;
                $fp = fopen(Yii::$app->basePath . "/weixinapi/wxconfigs/jsapi_ticket.json", "w");
                fwrite($fp, json_encode($data));
                fclose($fp);
            }
        } else {
     
            $ticket = $data->jsapi_ticket;
        }

        return $ticket;
    }

    private function getAccessToken()
    {
     
        // access_token 应该全局存储与更新,以下代码以写入到文件中做示例
        $data = json_decode(file_get_contents(Yii::$app->basePath . "/weixinapi/wxconfigs/access_token.json"));
        if ($data->expire_time < time()) {
     
            // 如果是企业号用以下URL获取access_token
            // $url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=$this->appId&corpsecret=$this->appSecret";
            $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$this->appId&secret=$this->appSecret";
            log::writeLog('getAccessToken的$url===' . $url);
            $res = json_decode($this->httpGet($url));
            $access_token = $res->access_token;
            log::writeLog('$access_token==' . $access_token);
            if ($access_token) {
     
                $data->expire_time = time() + 7000;
                $data->access_token = $access_token;
                $fp = fopen(Yii::$app->basePath . "/weixinapi/wxconfigs/access_token.json", "w");
                fwrite($fp, json_encode($data));
                fclose($fp);
            }
        } else {
     
            $access_token = $data->access_token;
        }
        return $access_token;
    }

    private function httpGet($url)
    {
     
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_TIMEOUT, 500);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_URL, $url);

        $res = curl_exec($curl);
        curl_close($curl);

        return $res;
    }
}


最后html分享页面联调

<!DOCTYPE html>
<html lang="en" style="width: 100%;height: 100%">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <meta name="format-detection" content="telephone=yes"/>
    <title>视频分享</title>

    <script type="text/javascript" src="js/jquery-3.1.1.min.js"></script>
    <script src="https://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>

    <script type="text/javascript">
        var appId;
        var nonceStr;
        var timestamp;
        var signature;

        var url;
        var rawString;


        $(document).ready(function () {
     
            let data = {
     
                "m": "weixin",
                "c": "getsignpackage",
                "url": window.location.href,
            }
            console.log("data=", data)

            $.ajax({
     
                contentType: "application/json; charset=UTF-8",
                type: "POST",
                url: "https://www.qipa250.com/weixinapi/index/index",
                data: JSON.stringify(data),
                dataType: 'json',
                success: res => {
     
                    if (res.status === 0) {
     
                        console.log(res)

                        appId = res.data.signPackage.appId;
                        nonceStr = res.data.signPackage.nonceStr;
                        timestamp = res.data.signPackage.timestamp;
                        signature = res.data.signPackage.signature;


                        shareParem();
                    } else {
     
                        console.log(res.msg)
                    }
                },
                error: err => {
     
                    console.log(err)
                }
            });
        });

        function GetRequest() {
     
            var url = location.search; //获取url中"?"符后的字串
            var theRequest = new Object();
            if (url.indexOf("?") != -1) {
     
                var str = url.substr(1);
                strs = str.split("&");
                for (var i = 0; i < strs.length; i++) {
     
                    theRequest[strs[i].split("=")[0]] = decodeURIComponent(strs[i].split("=")[1]);
                }
            }
            return theRequest;
        }

        function shareParem() {
     

            let ua = window.navigator.userAgent.toLowerCase();
            if (ua.indexOf('micromessenger') > 0) {
     //微信环境
                // alert("微信浏览器");
                wx.config({
     
                    debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
                    appId: appId, // 必填,公众号的唯一标识
                    timestamp: timestamp, // 必填,生成签名的时间戳
                    nonceStr: nonceStr, // 必填,生成签名的随机串
                    signature: signature,// 必填,签名,见附录1
                    jsApiList: [
                        'updateAppMessageShareData',
                        'updateTimelineShareData'
                    ]
                })

                wx.ready(function () {
     
                    //分享给朋友
                    wx.updateAppMessageShareData({
     
                        title: "分享标题",
                        desc: "分享描述",
                        link: "https://www.qipa250.com/share_short_video.html",
                        imgUrl: "http://www.qipa250.com/templets/54/picture/logo.png",
                        type: 'link', // 分享类型,music、video或link,不填默认为link
                        dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
                        success: function () {
     
                            // 用户确认分享后执行的回调函数
                        }
                    })

                    //分享到朋友圈
                    wx.updateTimelineShareData({
     
                        title: "分享标题",
                        link: "https://www.qipa250.com/share_short_video.html",
                        imgUrl: "http://www.qipa250.com/templets/54/picture/logo.png",
                        success: function () {
     
                            // 用户确认分享后执行的回调函数
                        }
                    })

                })

                wx.error(function (res) {
     
                    alert(res.errMsg);//错误提示
                })
            }else{
     
                // alert("其他浏览器");
            }

        }
    </script>
</head>
<body style="width: 100%;height: 100%;margin: 0;padding: 0;">

<div style="display: flex;justify-content:center;align-items:center;width: 100%;height: 100%;background-color: #000000">

    <video id="video" style="width: 100%" controls="controls" autoplay="autoplay"
           src="https://www.qipa250.com/CompanyVideo/20190510HH125020190510HH1250.mp4">
        您的浏览器不支持 video 标签。
    </video>


</div>

<div style="position: absolute;left:0;bottom: 50px;width: 50px;height: 50px">
    <a href="https://uri.amap.com/marker?position=116.397110,39.918423&name=北京市东城区景山前街4号">
       导航去这里
    </a>
</div>

<div style="position: absolute;right:0;bottom: 50px;width: 50px;height: 50px">
    <a href="tel:13800138000">
      拨打电话
    </a>
</div>


</body>
</html>

常见错误

invalid credential, access_token is invalid or not latest hint

是由于access_token过期了,导致生成的签名失败。分析上面的代码,发现将获取到的access_token缓存到localstorage的逻辑是有问题的,获取到的access_token默认有效期为2小时,如果重新请求API接口,新的access_token会覆盖原来的值,而我将access_token存入localstorage后,其实并没有做进一步的有效期的校验和定时刷新,所以过了有效期之后,自然就会出现上面的那个错误了

你可能感兴趣的:(Php,微信-小程序,Html)