本项目具体需求是短信跳转同一个小程序的不同页面,可以带参数。使用云函数和h5页面,开发时使用静态网站调试,后期h5页面后端另外部署的。
不属于原创,只是在使用的过程中参考以下教程,最终达到效果。现在记录下自己的实施过程。
微信小程序云函数使用教程【超详细】小程序开发——微信外环境静态h5跳转小程序 | 微信开放社区微信小程序云函数使用教程【超详细】
云开发环境静态H5页面,跳转到不同小程序不同页面的实现 | 微信开放社区
一.微信小程序云开发的使用过程
1.开通云开发服务、云开发权限设置、开通静态网站功能:
(1) 开通云开发服务,微信开发者工具——云开发
创建云开发环境,设置环境名称、付费方式(默认预付费,可以选按量付费,有一定免费额度的,无论个人开发调试还是公司项目使用,选按量付费就好了)
开通成功之后,概览界面右侧,能看到环境id,记住这个id,后边配置h5页面会用到。
(2)设置云开发权限,设置——权限设置,未登录用户访问云资源权限设置,勾选未登录用户访问权限:
(3) 开通静态网站,菜单栏”更多“——静态网站——开通
扫码确认,等初始化,可能需要点时间,无需等待,开通成功会有短信通知,可以先进行后边步骤
2.设置云开发环境
cloudfunctions 目录上边单击鼠标右键,设置当前环境,选择前边创建的云环境
二.微信小程序云函数的使用过程
1. 在根目录下“project.config.json”文件,添加字段
"cloudfunctionRoot": "cloudfunctions/",
2.在根目录下“app.json”文件,添加字段"cloud":true
"cloud":true,
3.新建云函数
(1)新建存储云函数的文件夹
在根目录自己下创建文件夹"cloudfunctions",由于刚才的配置,文件夹下会有个云的图标。
(2)新建云函数
短信跳转小程序云函数名称一定要是public,我使用别的名称后来跳转打不开找售后帮我查的,说这个函数名是固定的(--没写replace的地方不要改--)
请注意,这里的创建云函数不是在云开发控制台直接创建的,是需要通过小程序创建并部署的。虽然控制台也可以直接创建,但是不能直接用。(实测方法a可以)
a.方法一:右击刚才新建的文件夹"cloudfunctions",会有“新建Node.js云函数”选项,填写函数名称后,会自动生成一个文件目录,里面有三个文件夹(config.json,index.js,package.json)。这里创建的函数名称叫"public"。
b.方法二:参考 微信外环境静态h5跳转小程序,如何传参?-CSDN博客
官网云函数pubilc:点击下载
打开h5-open-miniprogram-cloudfunctions文件夹,将里面的public文件夹复制到云开发小程序中的 cloudfunctions 目录下。
(3)修改public文件夹里面的index.js文件
该index.js文件的具体内容,将 getUrlscheme函数中的path改成要调起小程序的页面路径。
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init()
// 云函数入口函数
exports.main = async (event, context) => {
const wxContext = cloud.getWXContext()
switch (event.action) {
case 'getUrlScheme': {
return getUrlScheme(event.path,event.query)
}
}
return 'action not found'
}
async function getUrlScheme(path,query) {
return cloud.openapi.urlscheme.generate({
jumpWxa: {
path: path || '/pages/login', // <!-- replace -->
query:query|| '',
},
// 如果想不过期则置为 false,并可以存到数据库
isExpire: false,
// 一分钟有效期
expireTime: parseInt(Date.now() / 1000 + 60),
})
}
4. 安装依赖
鼠标放到public目录上,单击鼠标右键,快捷菜单选中"在内建终端中打开",然后运行 npm install 安装依赖
5.上传部署云函数
public 目录上,单击鼠标右键,选择”上传并部署:云端安装依赖(不上传node_modules),
部署后,打开云开发控制台——云函数,就能看到前边创建部署的云函数了:等几秒钟,云函数就能部署成功了。
6.修改云函数权限
云开发控制台——云开发——云开发权限,自定义安全规则,点击右侧的“修改”
点允许所有用户访问,这样所有用户都可以免鉴权通过h5调起小程序了
可选的进阶的云函数安全规则模板(只放开了让 public 云函数支持未登录访问)
{
// * 为通配符,表示对所有函数适用
"*": {
// invoke 表示调用权限控制
// auth 包含鉴权信息,如果是未登录模式,则 auth == null
"invoke": "auth != null"
},
// 函数名,该规则优先级会高于通配符
"public": {
// 表示允许所有来源调用,包括未登录用户
"invoke": true
}
}
7.编写html文件
编辑官方下载的 jump-mp.html 文件,将所有标注<!-- replace -->的地方修改成真实的内容就好了。关键修改点在这三处:
因为项目跳转了同一小程序的不同页面,最后方案是短信里面添加一个标识type,然后不同type跳转不同地址。
主要参考了
云开发环境静态H5页面,跳转到不同小程序不同页面的实现 | 微信开放社区
实际代码如下
<html>
<head>
<title>打开小程序</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">
<script>
window.onerror = e => {
console.error(e);
alert('发生错误:' + e);
}
</script>
<!-- 调试用的移动端 console -->
<!-- <script src="https://cdn.bootcss.com/eruda/1.2.4/eruda.min.js"></script> -->
<!-- <script>eruda.init();</script> -->
<script>
function getQueryParam(key) {
const reg = new RegExp('(^|&)' + key + '=([^&]*)(&|$)', 'i');
const r = window.location.search.substr(1).match(reg);
if (r != null) {
return decodeURI(r[2]);
}
return null;
}
//设置 资源环境ID以及绑定的appid
var resAppId = ''; // <!-- appID,replace -->
var resEnv = ''; // <!-- 环境ID,replace -->
var resId = ''// <!-- 原始ID,replace -->
var launchIdx = getQueryParam('type');
var pagepath = ''
var catalogId = getQueryParam('id')
var queryKey = 'customerNoticeId=' + catalogId
if (launchIdx == 0) {
pagepath = '/pages/...'
} else {
pagepath = '/pages/...'
}
</script>
<!-- weui 样式 -->
<link rel="stylesheet" href="https://res.wx.qq.com/open/libs/weui/2.4.1/weui.min.css" />
<script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
<script src="https://res.wx.qq.com/open/js/cloudbase/1.1.0/cloud.js"></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: 25%
}
.public-web-container a {
position: absolute;
bottom: 40%
}
.wechat-web-container {
display: flex;
flex-direction: column;
align-items: center
}
.wechat-web-container div {
position: absolute;
top: 20%
}
.wechat-web-container wx-open-launch-weapp {
position: absolute;
bottom: 40%;
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">
<!-- <p>正在唤起微信小程序...</p> -->
<p>
<img style="width: 60px;height:60px;border-radius: 50%;display: block;margin: 10px auto;" src='https://cdn.lawbal.com/lvlian/login.svg'></img>
<span style="color:#17908E;text-align:center;margin:10px auto;">小程序名称</span>
</p>
<a id="public-web-jump-button" href="javascript:" class="weui-btn weui-btn_primary weui-btn_loading" onclick="openWeapp()">
<span id="public-web-jump-button-loading" class="weui-primary-loading weui-primary-loading_transparent"><i
class="weui-primary-loading__dot"></i></span>点击唤起小程序</a>
</div>
<div id="wechat-web-container" class="hidden">
<div style="width: 100%;">
<img style="width: 60px;height:60px;border-radius: 50%;display: block;margin: 0 auto;" src='https://cdn.lawbal.com/lvlian/login.svg'></img>
<p style="color:#17908E;text-align:center;margin:auto;">小程序名称</p>
</div>
<script>
// document.write('<wx-open-launch-weapp id="launch-btn" username="' + resId + '" path="' +
// pagepath + '" catalogId="' + catalogId + '">');
document.write('<wx-open-launch-weapp id="launch-btn" username="' + resId + '" path="' +
pagepath + '">');
document.write(
' <template><button style="width: 240px; height: 45px; text-align: center; font-size: 17px; display: block; margin: 0 auto; padding: 8px 24px; border: none; border-radius: 4px; background-color: #07c160; color:#fff;">打开微信小程序</button></template>'
);
document.write('</wx-open-launch-weapp>');
</script>
</div>
<div id="desktop-web-container" class="hidden">
<p class="font-size:26px;">请在手机上打开本链接</p>
</div>
</div>
<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 = isDesktop = false;
if (navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|IEMobile)/i)) {
isMobile = true
} else {
isDesktop = true
}
var isAndroid = ua.indexOf('android') > -1 || ua.indexOf('Adr') > -1;
var isOS = ua.indexOf('iPhone') > -1 || ua.indexOf('iPad') > -1 || ua.indexOf('Mac') > -1;
if (isWeixin) {
var containerEl = document.getElementById('wechat-web-container');
containerEl.classList.remove('hidden');
containerEl.classList.add('full', 'wechat-web-container');
var launchBtn = document.getElementById('launch-btn');
launchBtn.addEventListener('ready', function(e) {
console.log('开放标签 ready');
});
launchBtn.addEventListener('launch', function(e) {
console.log('开放标签 success');
});
launchBtn.addEventListener('error', function(e) {
console.log('开放标签 fail', e.detail);
});
wx.config({
debug: false,
appId: resAppId, // <!-- replace -->
timestamp: 0, // 必填,填任意数字即可
nonceStr: 'nonceStr', // 必填,填任意非空字符串即可
signature: 'signature', // 必填,填任意非空字符串即可
jsApiList: ['chooseImage'], // 必填,随意一个接口即可
openTagList: ['wx-open-launch-weapp'], // 填入打开小程序的开放标签名
})
} else if (isDesktop) {
// 在 pc 上则给提示引导到手机端打开
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')
var c = new cloud.Cloud({
identityless: true,
resourceAppid: resAppId, // 资源方宿主 小程序的AppID
resourceEnv: resEnv, // 资源方环境ID
})
await c.init();
window.c = c;
var buttonEl = document.getElementById('public-web-jump-button')
var buttonLoadingEl = document.getElementById('public-web-jump-button-loading')
try {
await openWeapp(() => {
buttonEl.classList.remove('weui-btn_loading');
buttonLoadingEl.classList.add('hidden');
})
} catch (e) {
console.log('error', e)
buttonEl.classList.remove('weui-btn_loading')
buttonLoadingEl.classList.add('hidden');
throw e
}
}
})
async function openWeapp(onBeforeJump) {
var c = window.c
const res = await c.callFunction({
name: 'public', // 宿主环境中的云函数,注意开启权限
data: {
action: 'getUrlScheme',
appid: resAppId,
path: pagepath,
query: queryKey || '',
},
})
if (onBeforeJump) {
onBeforeJump();
}
location.href = res.result.openlink;
}
</script>
</body>
</html>
云环境Id,小程序开发工具点击云开发,右上角有个环境ID,复制就可以。
主要参考小程序开发——微信外环境静态h5跳转小程序 | 微信开放社区
8.上传h5页面到云开发环境
云开发控制台——更多——静态网站——文件管理,点击上传文件,选择上边改好的h5页面即可
上传成功:
9.测试验证、配置域名
静态网站窗口,选择”文件管理“,点击详情,可以看到已经下载地址,可以直接复制这个地址到手机浏览器中直接打开,如果前边操作没有遗漏的话,就能在浏览器中调起微信小程序了。
10.后续我这边使用的短信地址是通过阿里云部署的,就不补充相关了
微信云开发配置域名有一篇参考文章
微信云开发配置自有域名(短信跳转小程序)_请使用自己的专属域名访问微信开发工具-CSDN博客
三.最近要解绑换绑新的腾讯云账号,云开发部分需要重新开通,云环境需要重新设置一下。
云开发按文章的步骤走下来都是ok的。换绑按官方文档来就可以,换绑腾讯云账号只影响小程序云开发部分的功能,其他都不受影响。
以下是官方文档: