h5 跳转微信小程序

4,968 阅读2分钟

概述

普通的H5是无法跳转小程序的。在手机微信内打开的H5网页可通过开放标签<wx-open-launch-weapp>跳转微信小程序(目前电脑微信不会渲染跳转按钮)。具体使用、权限说明,请阅读微信官方文档

使用步骤文档有详细说明,这里简单概括如下:

  1. 登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名” 。
  2. 后端开发提供获取签名相关字段的接口。
  3. 微信公众平台查看所需跳转的小程序原始id,注意是gh_开头的。
  4. 按官方文档准备html文件,部署到绑定域名的服务器上。(文末有完整的示例代码,供参考)
  5. 在手机微信内打开部署好的html文件。正常情况下,会出现小程序的按钮,点击可跳转小程序。

可能遇到的错误

这些都时我开发遇到的错误,下面列出了原因和解决办法。如果你也遇到了,希望对你有帮助。

非法签名

错误描述:jssdk 报错 config:invalid signature。如下图:

原因:签名用的url是后端自己取,

解决办法:前端动态获取location.href.split('#')[0],传给服务端就正确啦。

const url = encodeURIComponent(location.href.split('#')[0]); 
fetch(`/wechat/index?url=${url}`).then(res => {
    return res.json()
})

如果不是url的问题,就麻烦后端同学对照文档,阅读附录1-JS-SDK使用权限签名算法、附录5-常见错误及解决方法,确认签名算法是否正确。

信息不完整,无法启动

错误描述:点击打开小程序的按钮,点击允许后,toast提示 “信息不完整,无法启动”。

原因:开发标签的 username 不正确。我当时就是写成了配套公众号的原始id。/(ㄒoㄒ)/~~

解决:请再次你的确定<wx-open-launch-weapp> 标签的 username 参数是 gh_开头的目标小程序的原始id

jweixin引入时报错

错误描述:uni-app 项目中,vue文件 require('../../common/jweixin-1.6.0.js'),报错。

原因:jweixin里执行this.document.titlethis期望指向window,但uni-app打包构建后this指向了undefined

解决办法:

  1. jweixin-1.6.0.js源码文件,将第一个this 改成window
  2. uni-app h5 支持自定义模板,在模板中直接使用script标签引入就没有这个问题啦。
  3. 更多解法参考这个回答

vue 文件template标签冲突

错误描述:将如下内容粘贴到vue文件的template出现一大堆报错。

<wx-open-launch-weapp id="launch-btn" username="gh_xxxxxxx" path="pages/brand/brand.html">
    <template>
        <style>.btn {padding: 10px;}</style>
        <button class="btn">打开小程序</button>
    </template>
</wx-open-launch-weapp>

官方说明如下:

对于Vue等视图框架,为了避免template标签冲突的问题,可使用<script type="text/wxtag-template"><script>进行代替,来包裹插槽模版和样式。

按说明,修改成下面这样,就不报错啦。

<wx-open-launch-weapp id="launch-btn" username="gh_xxxxxxx" path="pages/brand/brand.html">
    <script type="text/wxtag-template">
        <style>.btn {padding: 10px;}</style>
        <button class="btn">打开小程序</button>
    </script>
</wx-open-launch-weapp>

wx-open-launch-weapp 里标签样式问题

问题描述:打开小程序按钮,要固定在屏幕右下方,使用fixed定位,发现标签不见了?按钮line-height设置为100rpx,不生效?

官方说明如下:

页面中与布局和定位相关的样式,如position: fixed; top -100;等,尽量不要写在插槽模版的节点中,请声明在标签或其父节点上。

除了官方说明,实践总结如下几点:

  1. 插槽模版的节点,不能使用rpx,定义的scss变量名当然也不可以(复制粘贴注意下/(ㄒoㄒ)/~~)。
  2. 插槽模版的节点,设置宽高100%无效。
  3. 父节点可设置fixed等,定位、布局类样式可写在父节点上,插槽节点放在里面就能实现你想要的布局。
  4. 父节点使用flex 布局,可能会出现样式。(本来想用flex布局实现居中的,结果不行)

html 示例代码

<html>
<head>
    <meta charset="utf-8">
    <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
</head>
<body>
    <script>
        // 动态获取当前页面 url, 传给后端用于签名 
        const url = encodeURIComponent(location.href.split('#')[0]); 
        fetch(`/wechat/index?url=${url}`).then(res => {
            return res.json()
        }).then(({ signPackage }) => {
            const { timestamp, nonceStr, signature, appId } = signPackage
            wx.config({
                debug: true, // 调试时可开启,调用的所有api的返回值会在客户端alert出来
                appId, // 必填,公众号的唯一标识
                timestamp, // 必填,生成签名的时间戳
                nonceStr, // 必填,生成签名的随机串
                signature, // 必填,生成签名的随机串
                jsApiList: ['openLocation'], // 必填,需要使用的JS接口列表
                openTagList: ['wx-open-launch-weapp'], // 需要使用的开放标签列表
            })
        })
    </script>

    <wx-open-launch-weapp id="launch-btn" username="gh_xxxxxxx" path="pages/brand/brand.html">
        <template>
            <style>
                .btn {
                    padding: 10px;
                }
            </style>
            <button class="btn">打开小程序</button>
        </template>
    </wx-open-launch-weapp>

    <script>
        var btn = document.getElementById('launch-btn');
        btn.addEventListener('launch', function (e) {
            console.log('success');
        });
        btn.addEventListener('error', function (e) {
            console.log('fail', e.detail);
        });
    </script>
</body>
</html>

uni-app 项目的 vue 示例代码

<template>
	<view class="wxopen">
        <wx-open-launch-weapp
            id="launch-btn"
            username="gh_xxxxxx"
            path="pages/goods/goods.html?id=123"
        >
            <script type="text/wxtag-template">
                <style>
                    .btn {
                        margin-top:5px;
                        margin-left:5px;
                        padding:5px;
                        width:40px;
                        height:40px;
                        color:#fff;
                        font-size:10px;
                        background:#e60012;
                        border-radius:50%;
                        text-align:center;
                        box-shadow: 0 0 5px rgba( 245, 67, 81, .7);
                    }
                </style>
                <div class="btn">
                    去小程序买它
                </div>
            </script>
        </wx-open-launch-weapp>
    </view>
</template>
<script>
   const wx = require('../../common/jweixin-1.6.0.js')
   export default{
        onLoad() {
        	this.initWxopen()  
        },
        methods: {
            initWxopen() {
                const url = location.href.split('#')[0]
                fetch(`/wechat/index?url=${url}`).then(res => {
                    return res.json()
                }).then(({signPackage}) => {
                    const {timestamp, nonceStr, signature,appId} = signPackage
                    wx.config({
                        // debug: true, // 调试时可开启, 调通了就关啦
                        appId, // 必填,公众号的唯一标识
                        timestamp, // 必填,生成签名的时间戳
                        nonceStr, // 必填,生成签名的随机串
                        signature, // 必填,生成签名的随机串
                        jsApiList: ['openLocation'], 
                        openTagList:['wx-open-launch-weapp'],
                    })
                })
            }
        }
    }
</script>
<style>
.shop-wxopen{
	position: fixed;
	bottom: 80px;
	right: 10px;
	width: 60px;
	height: 60px;
	text-align: center;	
}
</style>