在企业微信中通过h5如何唤起小程序?

问题概述

近期有个需求,需要在企业微信中通过链接的方式唤起我们企业微信的内部自建应用小程序,本以为会很简单,因为微信小程序提供有类似能力通过urlscheme生成类似的于weixin://dl/....的短链,跳转这个短链就可以跳转到对应的小程序。但是在企业微信的开发文档中并没有类似的方法。。。

寻找解决办法

在企业微信的官方文档中只提供了这种方式来跳转小程序

js 复制代码
wx.invoke('launchMiniprogram', {
        	"appid" : "wx062aaa5507909631", // 需跳转的小程序appid
		"path" : "pages/home/index.html", // 所需跳转的小程序内页面路径及参数。非必填
        }, function(res) {
			if(res.err_msg == "launchMiniprogram:ok") {
				// 正常
			} else {
				// 错误处理
			}
    	}
);

众所周知微信相当严格,要使用launchMiniprogram之前要先成功调用agentConfig 相关注意事项

使用这些api时要引入相关的js-sdk。 这里我以一个简单的h5举个🌰

step1 注入js-sdk

html 复制代码
<script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>

首先引入这个js-sdk 引入后并不能直接使用需要相关权限验证配置官方文档

先通过config接口注入权限验证配置

js 复制代码
wx.config({
    beta: true,// 必须这么写,否则wx.invoke调用形式的jsapi会有问题
    debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
    appId: '', // 必填,企业微信的corpID,必须是本企业的corpID,不允许跨企业使用
    timestamp: '', // 必填,生成签名的时间戳
    nonceStr: '', // 必填,生成签名的随机串
    signature: '',// 必填,签名,见 附录-JS-SDK使用权限签名算法
    jsApiList: [] // 必填,需要使用的JS接口列表,凡是要调用的接口都需要传进来
});
  1. appId : 一定是你所在企业的corpId,未来你在A企业用这个跳转逻辑,你就填A企业的id
  2. timestamp : 随机的时间戳(一般采用当前时间戳,建议在链路跑通前写死)
  3. nonceStr : 随机的字符串(建议在链路跑通前写死)
  4. signature : 下面单独讲,
  5. jsApiList : 需要使用到的接口都需要传进来

signature签名生成(官方文档

要想生成这个签名首先需要 拼接一下这个字符串jsapi_ticket=JSAPITICKET&noncestr=NONCESTR&timestamp=TIMESTAMP&url=URL

有两个注意点:

  1. 字段值采用原始值,不要进行URL转义;
  2. 必须严格按照如下格式拼接,不可变动字段顺序。

然后对这个字符串进行sha1加密就是我们所需要的签名了

其中 noncestrtimestamp 就是之前生成的随机值,url 就是当前h5的地址 这里的 jsapi_ticket 使用的是企业的jsapi_ticket

获取企业jsapi_ticket(官方文档)

请求URL: qyapi.weixin.qq.com/cgi-bin/get... 通过这个接口就能拿到 ticket ACCESS_TOKEN不同的应用方式也不同,具体参考官方文档

有了ticket就可以生成签名了 官方也提供了检验工具,来帮助我们查看生成的签名是否正确

有了签名config基本就注入成功了,如果失败的话也会有提示。

step2 agentConfig注入应用的权限

官方文档

这里和config的注入方法一样,只有一个区别就是这里获取的jsapi_ticket应用的jsapi_ticket

注:获取企业的jsapi_ticket和应用的jsapi_ticket调用接口是不同的(这里提醒下因为之前踩过坑),企业的jsapi_ticket的比较长应用的比较短

官方也说过可以直接通过agentConfig注入应用的权限,而不需要注入config,但是保险起见以后也不知道会不会有其他的需求建议一起注入。

code

html 复制代码
<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>H5</title>
    <script>//sha1加密的cdn</script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/core.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/enc-base64.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/sha1.min.js"></script>


    <script>//js-sdk</script>
    <script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
    <script src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js"></script>
</head>

<body>
    <button id="btn" style="width: 100vw; height: 100px; text-align: center">click</button>
</body>
<script src="./demo.js"></script>

</html>
js 复制代码
//demo.js

//获取随机字符串
function generateRandomString(length) {
    var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    var result = new Array(length).fill(0).map(() => chars.charAt(Math.floor(Math.random() * chars.length))).join('');
    return result;
};


//获取签名
function getsignature({ time, str, isapp }) {
    //提前获取的企业jsapi_ticket
    const ticket = "HoagFKDcsGMVCIY2vOjf9l_kslAeMzZBEEdLJZ8kfUR7Ci6q5SNCZwDm0MCvUqljsw15y8MSRwlghNtNXlxXYA"
    //提前获取的应用jsapi_ticket
    const appticket = 'Jt9ZPs1ZB1bj0CorBIwBgA=='
    const lastTicket = isapp ? appticket : ticket;
    const data = `jsapi_ticket=${lastTicket}&noncestr=${str}&timestamp=${time}&url=${location.href}`
    return CryptoJS.SHA1(data).toString();
};

//给btn注册点击事件 点击后跳转小程序
document.querySelector('#btn').addEventListener('click', function () {
    document.querySelector('.txt').innerHTML = location.href
    const nowTime = Math.floor(new Date().getTime() / 1000);
    const nonStr = generateRandomString(16)
    const signature = getsignature({ time: nowTime, str: nonStr })
    const appsignature = getsignature({ time: nowTime, str: nonStr, isapp: true })
    wx.config({
        beta: true,// 必须这么写,否则wx.invoke调用形式的jsapi会有问题
        debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
        appId: 'wwxxxxxxxxxxx', // 必填,企业微信的corpID,必须是本企业的corpID,不允许跨企业使用
        timestamp: nowTime, // 必填,生成签名的时间戳
        nonceStr: nonStr, // 必填,生成签名的随机串
        signature: signature,// 必填,签名,见 附录-JS-SDK使用权限签名算法
        jsApiList: ['invoke'], // 必填,需要使用的JS接口列表,凡是要调用的接口都需要传进来

    })
    wx.agentConfig({
        corpid: 'ww0xxxxxxx', // 必填,企业微信的corpid,必须与当前登录的企业一致
        agentid: '100000000', // 必填,企业微信的应用id (e.g. 1000247)
        timestamp: nowTime, // 必填,生成签名的时间戳
        nonceStr: nonStr, // 必填,生成签名的随机串
        signature: appsignature,// 必填,签名,见附录-JS-SDK使用权限签名算法
        jsApiList: ['invoke', 'launchMiniprogram'], //必填,传入需要使用的接口名称
        success: function (res) {
            wx.invoke('launchMiniprogram', {
                "appid": "wxaaaaaaaaa", // 需跳转的小程序appid
            }, function (res) {
                wx.closeWindow() //关闭当前h5
            }
            )
        },
        fail: function (res) {
            setTxt(JSON.stringify('wx.agentConfig erroer' + JSON.stringify(res)))
            if (res.errMsg.indexOf('function not exist') > -1) {
                alert('版本过低请升级')
            }
        }
    });

})

如果有什么问题欢迎在评论区留言

相关推荐
慧一居士23 分钟前
flex 布局完整功能介绍和示例演示
前端
DoraBigHead25 分钟前
小哆啦解题记——两数失踪事件
前端·算法·面试
一斤代码6 小时前
vue3 下载图片(标签内容可转图)
前端·javascript·vue
中微子6 小时前
React Router 源码深度剖析解决面试中的深层次问题
前端·react.js
光影少年6 小时前
从前端转go开发的学习路线
前端·学习·golang
中微子6 小时前
React Router 面试指南:从基础到实战
前端·react.js·前端框架
3Katrina7 小时前
深入理解 useLayoutEffect:解决 UI "闪烁"问题的利器
前端·javascript·面试
前端_学习之路7 小时前
React--Fiber 架构
前端·react.js·架构
伍哥的传说8 小时前
React 实现五子棋人机对战小游戏
前端·javascript·react.js·前端框架·node.js·ecmascript·js
qq_424409198 小时前
uniapp的app项目,某个页面长时间无操作,返回首页
前端·vue.js·uni-app