H5跳转任意微信小程序(含完整测试代码):遇事无难易,而能于敢为。

Auth:PigMoMo       Date:2023/09/3       Cat:知识与信息       Word:共5422字

今天心血来潮想实现下微信内H5跳转任意小程序,非URL Scheme:weixin://dl/business/?t=TICKET 跳转。通过查询微信公众号文档、搜索与自己的实践,总结出以下几个要点。

  1. 一定要使用微信官方工具进行开发,不要在个人微信上进行测试,否则无法判断是否获取到jsApiList权限和openTagList标签。

  2. 一定要使用认证微信公众号,或者非个人认证的小程序绑定的JS安全域名才能申请到wx-open-launch-weapp标签。

  3. signature生成前必须把服务器IP加入白名单。

注意:access_tokenjsapi_ticket的获取次数每天有限,在测试阶段,获取次数比较少,不影响,但在实际开发中,一定要进行储存,并进行前后端分离。 该代码部分内容已经删除,请搜索替换replace处的代码为自己的数据,本人不保证该代码能够正常运行,仅做测试参考。

<?php

// 获取access_token
function getAccessToken($appid, $appsecret) {
    $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appid&secret=$appsecret";
    $response = file_get_contents($url);
    $data = json_decode($response, true);
    return $data['access_token'];
}

// 获取jsapi_ticket
function getJsApiTicket($accessToken) {
    $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=$accessToken";
    $response = file_get_contents($url);
    $data = json_decode($response, true);
    return $data['ticket'];
}

// 生成随机字符串
function generateNonceStr($length = 16) {
    $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    $nonceStr = "";
    for ($i = 0; $i < $length; $i++) {
        $nonceStr .= $chars[mt_rand(0, strlen($chars) - 1)];
    }
    return $nonceStr;
}

// 生成签名
function generateSignature($ticket, $nonceStr, $timestamp, $url) {
    $params = array(
        'jsapi_ticket=' . $ticket,
        'noncestr=' . $nonceStr,
        'timestamp=' . $timestamp,
        'url=' . $url
    );
    sort($params, SORT_STRING);
    $string1 = implode('&', $params);
    $signature = sha1($string1);
    return $signature;
}

// 填写已认证公众号的AppID和AppSecret
$appid = 'replace';
$appsecret = 'replace';

// 填写当前页面的URL
$url = 'replace';

// 获取access_token
$accessToken = getAccessToken($appid, $appsecret);

// 获取jsapi_ticket
$jsapiTicket = getJsApiTicket($accessToken);

// 生成随机字符串和时间戳
$nonceStr = generateNonceStr();
$timestamp = time();

// 生成签名
$signature = generateSignature($jsapiTicket, $nonceStr, $timestamp, $url);

// 构建可以打开小程序的HTML代码
$miniProgramHtml = <<<HTML
<!DOCTYPE html>
<html>
    <head>
        <title>微信公众号-升格enhancer</title>
        <meta name="viewport" content="width=device-width,user-scalable=no,initial-scale=1,maximum-scale=1">
            <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js">
            </script>
            <script>
                function docReady(fn){if(document.readyState==='complete'||document.readyState==='interactive'){fn()}else{document.addEventListener('DOMContentLoaded',fn)}}
                docReady(async function() {
                    var ua = navigator.userAgent.toLowerCase();
                    var isWXWork = ua.match(/wxwork/i) == 'wxwork';
                    var isWeixin = !isWXWork && ua.match(/MicroMessenger/i) == 'micromessenger';
                    var isMobile = false;
                    var isDesktop = false;
                    if (navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|IEMobile)/i)) {isMobile = true} else {isDesktop = true}
                    if (isWeixin) {
                        wx.config({debug: true,appId: '{$appid}',timestamp: '{$timestamp}',nonceStr: '{$nonceStr}',signature: '{$signature}',jsApiList:['closeWindow','showMenuItems','hideAllNonBaseMenuItem'],openTagList:['wx-open-launch-weapp'],});
                        //非认证公众号申请wx-open-launch-weapp会返回空数组

                        var containerEl = document.getElementById('wechat-web-container');
                        containerEl.classList.remove('hidden');
                        containerEl.classList.add('full', 'wechat-web-container');
                        var launchBtn = document.getElementById('weapp-btn');
                        //wx-open-launch-weapp没申请到以下代码不会执行,就不会展示跳转按钮,也不会报错
                        launchBtn.addEventListener('ready', function (e) {
                            wx.hideAllNonBaseMenuItem();
                            wx.showMenuItems({menuList: ['menuItem:copyUrl'] });
                        });
                        launchBtn.addEventListener('launch', function (e) {wx.closeWindow();});
                        launchBtn.addEventListener('error', function (e) {alert("error");});          wx.error(function(res){alert(res);});
                    }else if(isDesktop){
                        var containerEl = document.getElementById('desktop-web-container');
                        containerEl.classList.remove('hidden');
                        containerEl.classList.add('full', 'desktop-web-container');
                    }else{
                        var containerEl = document.getElementById('public-web-container');
                        containerEl.classList.remove('hidden');
                        containerEl.classList.add('full', 'public-web-container');
                    }
                });
            </script>
            <style>.hidden{display:none}.full{position:absolute;top:0;bottom:0;left:0;right:0}.public-web-container{display:flex;flex-direction:column;align-items:center}.public-web-container p{position:absolute;top:45%}.public-web-container a{position:absolute;bottom:20%}.wechat-web-container{display:flex;flex-direction:column;align-items:center}.wechat-web-container p{top:40%}.wechat-web-container wx-open-launch-weapp{bottom:20%;left:0;right:0;display:flex;flex-direction:column;align-items:center}.desktop-web-container{display:flex;flex-direction:column;align-items:center}.desktop-web-container p{position:absolute;top:40%}</style>
    </head>
    <body>
        <div class="page full">
            <div id="public-web-container" class="hidden">
            </div>
            <div id="wechat-web-container" class="hidden" style="display:flex;flex-direction:column;-webkit-box-align:center;align-items:center;height:100%;">
                <div style="flex: 1 1 0%;place-self: stretch;">
                </div>
                <wx-open-launch-weapp id="weapp-btn" appid="replace" path="replace">
                    <template>
                        <style>.btn{padding:9px;border:none;background-color:#07c160;color: #fff;font-weight:800;width:184px;border-radius:10px;font-size:19px;line-height: 1.88235294;padding: 8px 24px;}:focus{outline:0;}.btn2{padding:9px;border:none;background:linear-gradient(89.97deg, #00BFBF 50%, #99B3FF 99.97%);color: #fff;font-weight:800;width:184px;border-radius:10px;font-size:19px;line-height:23px;}</style>
                        <div style="width: 100%;text-align: center;">
                            <button class="btn">&#21069;&#24448;&#23567;&#31243;&#24207;</button>
                        </div>
                    </template>
                </wx-open-launch-weapp>
                <div style="flex: 1 1 0%;place-self: stretch;max-height: 14.6%;">
                </div>
            </div>
            <div id="desktop-web-container" class="hidden">
            </div>
        </div>
    </body>
</html>
HTML;

// 输出HTML代码
echo $miniProgramHtml;
?>

PS:本人非专业开发人员,写这篇文章以备份与总结一次兴趣使然的过程,有其他问题请善用搜索与询问其他专业人员。

评论已关闭!