在企业微信中通过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('版本过低请升级')
            }
        }
    });

})

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

相关推荐
zqx_720 分钟前
随记 前端框架React的初步认识
前端·react.js·前端框架
惜.己37 分钟前
javaScript基础(8个案例+代码+效果图)
开发语言·前端·javascript·vscode·css3·html5
什么鬼昵称1 小时前
Pikachu-csrf-CSRF(get)
前端·csrf
长天一色1 小时前
【ECMAScript 从入门到进阶教程】第三部分:高级主题(高级函数与范式,元编程,正则表达式,性能优化)
服务器·开发语言·前端·javascript·性能优化·ecmascript
NiNg_1_2342 小时前
npm、yarn、pnpm之间的区别
前端·npm·node.js
秋殇与星河2 小时前
CSS总结
前端·css
BigYe程普2 小时前
我开发了一个出海全栈SaaS工具,还写了一套全栈开发教程
开发语言·前端·chrome·chatgpt·reactjs·个人开发
余生H2 小时前
前端的全栈混合之路Meteor篇:关于前后端分离及与各框架的对比
前端·javascript·node.js·全栈
程序员-珍2 小时前
使用openapi生成前端请求文件报错 ‘Token “Integer“ does not exist.‘
java·前端·spring boot·后端·restful·个人开发
axihaihai2 小时前
网站开发的发展(后端路由/前后端分离/前端路由)
前端