一、公众号联系云函数
微信开发文档上有实例,可直接复制粘贴,根据内容需要改改就可以了。
这里是实例文档地址:实例传送门
首先需要讲的是,实例流程:
1.微信开发文档前面有说如果公众号联系小程序云函数的话,首先需要配置公众号的后台,需要的配置有:微信公众号后台的js安全域名和网页授权地址,还要在微信开发者工具上配置云函数,小程序的云函数要环境共享给公众号。
文档上都有说到,再次不过多讲述,附上地址:
微信公众号地址:微信公众平台传送门
小程序的配置附上图片引导:
打开微信开发者工具,打开项目,点击云开发:
然后点击更多——环境共享:
第一次进来的话,是没有关联的公众号的,需要点击添加共享,输入相应的公众号信息,才能关联成功,成功之后就会像我这样的显示出关联的公众号信息:
到这里就算是配置完了,其他地方没想到的文档上会有。
2.复制实例后,前面的部分都是引入一些必要的js文件以及初始化HTML的结构。
3.接下来是需要改的地方,实例也标出来了,公众号的appid以及云函数资源方小程序的appid和云函数的云环境id,还有什么样的授权方式,两个选一个,还有回调地址,这个回调地址一定要填上传的服务器地址全称,不是和公众号后台配置的js安全域名和网页授权地址一样的,公众号后台配置的那是域名,这个回调是地址全称。
下面是我的项目信息实例:
4.接下来就可以直接打开了,这要注意,如果在电脑上的浏览器打开,显示界面会是这样的:
点击登录后就会提示:
因为这是PC端,而公众号是微信端的,也就是需要用微信内部浏览器才可以打开,我们可以把VScode文件上传到服务器,然后在把地址发送到手机微信上,直接点击链接在微信内打开,也可以用微信开发者工具的网页调试打开:
这里要注意,如果公众号后台没有设置你是这个公众号的开发者,你是不可以调试的,有提示,一看就知道去那里配置了,打开之后把上传的服务器地址复制到红框里,刷新就可以了。
5.以第二种授权方式为例,也就是上面第3我改的那里信息登录用snsapi_userinfo,点击登录之后,点击右下角的小齿轮(那是控制台),我们可以看到第一次登录会在10s后跳转申请信息授权页面。等待10s后,页面会跳转到信息授权页面,我们点击同意授权,就登陆了,会跳回到原来这个首页,再点击一下登录,其他的选项就会显示出来了,就像这样:
注意:这里一定要注意!!!如果登录报错了,不管报的什么错误,基本只有一种可能,那就是信息填错了,也可能是配置错了,但我感觉不至于,就那两步;一定要注意信息是不是对的,就是改的那里,我写这个项目的时候,因为资源方小程序appid是公司的,而我一直以为用的是我的小程序appid,结果我在这卡了一天,找了n个CSDN文章、看了n遍文档、头发掉了n根、抽了三颗烟,最后才发现是appid填错了,改了之后直接就跑通了。
6.下面的选项就要看公司需要了,就比如我的项目是需要获取用户信息,实现微信支付,还要分享。
实例上有获取用户信息,其中包括用户头像和昵称,还有用户的openid,如下:
7.接下来是分享,看了看文档,是有介绍的,和微信小程序的分享差不多。
第二个按钮接口里还有保存图片和获取地理位置两个实例,不需要的话可以return掉。
这里是用的第二个按钮接口做的分享,文档上也说了,写在ready里,是用的接口列表也需要在上面填上,必填,否则会报错。分享的正确用法是登陆之后,点一下第二个按钮接口,没有报错就可以,点击右上角的三个点,分享之后就会有自定义的内容了:
再此附上地址:微信开放文档 公众号分享传送门
8.接下来就是调起微信支付了。
我是又写了个按钮接口来展示微信支付的,接下来,看我的操作:
其实也就是比着葫芦画瓢,看实例其他的是怎么写的,自己就仿照着写一个就可以了。
我这里是写了按钮接口后,访问了以前写的一个调起微信支付的云函数,给我返回了支付统一下单需要的所有信息,然后紧接着用了公众号调起微信支付的方法。
这里是文档传送门:公众号调微信支付传送门
前端h5页面的源代码:
<html> <head> <title>云开发 Web 能力极简示例</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 => { alert('window error ' + e) } </script> <!-- 调试用的移动端 console --> <script src="https://cdn.jsdelivr.net/npm/eruda"></script> <script>eruda.init();</script> <!-- 公众号 JSSDK --> <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script> <!-- 云开发 Web SDK --> <script src="https://res.wx.qq.com/open/js/cloudbase/1.1.0/cloud.js"></script> <script> // 公众号基本信息:请修改下列字段使用本示例 const WX_RESOURCE_APPID = 'xxxx' /* 资源方 AppID */ const WX_RESOURCE_ENVID = 'xxxxx' /* 资源方云开发环境 ID */ const WX_OFFICIAL_ACCOUNT_APPID = 'xxxxxxx'/* 公众号 AppID */ const WX_AUTH_TYPE = 'snsapi_userinfo' /* 选择需要的授权方式,snsapi_base 或 snsapi_userinfo */ const WX_REDIRECT_URI = 'http://test1001.wlphp.com/demo04/a.html' /* 回调 URL */ // 示例配置 const isPersistLoginInfo = true // 是否需要保留登录态信息到 window 中,只有 snsapi_userinfo 方式需要 if (window.wx) { window.cloud = wx.cloud } var urlSearch = new URLSearchParams(location.search) var accessToken = urlSearch.get('access_token') var refreshToken = urlSearch.get('refresh_token') /** * 检查/发起登录 * 1. 函数会检查当前是否已登录(checkLogin) * 2. 如果未登录,会 10s 后自动发起登录(startLogin) * 3. 如果已登录,会初始化实例,使用指定的微信云开发资源 */ window.doLogin = async () => { try { const checkLoginOptions = { provider: 'OfficialAccount', appid: WX_OFFICIAL_ACCOUNT_APPID, } if (urlSearch.get('oauthredirect') === '1') { checkLoginOptions.accessToken = accessToken checkLoginOptions.refreshToken = refreshToken } console.log(`checkLogin options: `, checkLoginOptions) const result = await cloud.checkLogin(checkLoginOptions) console.log(`checkLogin result: `, result) if (isPersistLoginInfo) { window.checkLoginRes = result } if (result.errCode === 0 && result.loggedIn) { console.log(`checkLogin success`) const instance = window.instance = new cloud.Cloud({ appid: WX_OFFICIAL_ACCOUNT_APPID, resourceAppid: WX_RESOURCE_APPID, resourceEnv: WX_RESOURCE_ENVID, }) const initResult = await instance.init() console.log(`instance inited`, initResult) console.log(`can use cloud instance to access resource now !`) const els = [...document.getElementsByClassName('display-none')] els.forEach(el => el.classList.remove('display-none')) } else { console.log(`checkLogin with sdk errCode ${result.errCode} errMsg ${result.errMsg}, will start oauth in 5s`) setTimeout(() => { try { cloud.startLogin({ provider: 'OfficialAccount', appid: WX_OFFICIAL_ACCOUNT_APPID, scope: WX_AUTH_TYPE, redirectUri: WX_REDIRECT_URI, }) } catch (e) { console.error(`startLogin fail: ${e}`) console.warn(`will start OfficialAccount OAuth login in 5s.`) } }, 5000) } } catch (e) { console.error(e) } } /** * 获取用户信息的示例 * 1. 需在登录后调用 * 2. 网页授权的方式需为 snsapi_userinfo * 3. 从 checkLogin 结果中获取用户信息 cloudID(已在 doLogin 函数中先暂存到全局变量 checkLoginRes) * 4. 调用云函数换取 cloudID 信息 */ window.getUserInfo = async () => { if (!checkLoginRes) throw new Error('获取登录信息失败,请确认授权方式以及是否保存了登录信息') try { if (checkLoginRes.cloudID) { const res = await instance.callFunction({ name: 'echo', data: { userInfoData: new instance.CloudID(checkLoginRes.cloudID), }, }) const cloudData = res.result.userInfoData if (cloudData.data) { const userInfoImg = document.querySelector('#userinfo .avatar') userInfoImg.src = cloudData.data.avatarUrl const userInfoName = document.querySelector('#userinfo .name') userInfoName.innerText = cloudData.data.nickName const userInfoOpenID = document.querySelector('#userinfo .openid') userInfoOpenID.innerText = cloudData.data.openId const userInfoDiv = document.getElementById('userinfo') userInfoDiv.style.cssText = '' } else { console.warn(`cloudID data error: `, cloudData) alert(`cloudID 信息获取错误,请查看调试器报错信息`) } } else { alert(`找不到 cloudID,请确认网页授权方式为 snsnapi_userinfo`) } } catch (e) { console.error(`error: ${e} ${e.stack}`) } } /** * 使用 JSSDK 的示例 * 1. 需在登录后调用 * 2. 首先会使用云开发 web sdk 提供的 getJSSDKSignature 方法获取网页所需的 wx.config 的签名 * 3. 调用 wx.config * 4. wx.config 成功之后尝试调用选择图片和获取地理位置作为示例 */ window.useJSSDK = async () => { try { const instance = window.instance console.log(`url: ${location.href}`) const res = await instance.getJSSDKSignature({ url: location.href, }) console.log(`jssdk sign res: ${JSON.stringify(res)}`) const configOpt = { debug: true, // 开启调试模式,调用的所有 api 的返回值会在客户端 alert 出来,若要查看传入的参数,可以在 pc 端打开,参数信息会通过 log 打出,仅在 pc 端时才会打印。 appId: WX_OFFICIAL_ACCOUNT_APPID, // 必填,公众号的唯一标识 timestamp: res.timestamp + '', // 必填,生成签名的时间戳 nonceStr: res.nonceStr, // 必填,生成签名的随机串 signature: res.signature,// 必填,签名 jsApiList: ['chooseImage', 'getLocation', 'updateTimelineShareData','updateAppMessageShareData'] // 必填,需要使用的 JS 接口列表 } console.log(`wx.config opt ${JSON.stringify(configOpt)}`) wx.config(configOpt) console.log(`wx.config executed`) wx.ready(() => { console.log(`wx.ready triggered`) //分享朋友 wx.updateAppMessageShareData({ title: '测试标题', // 分享标题 desc: '测试内容', // 分享描述 link: 'http://test1001.wlphp.com/demo04/a.html?a=1&b=2', // 分享链接,该链接域名或路径必须与当前页面对应的公众号 JS 安全域名一致 imgUrl: 'https://636c-cloud1-8gsu5k8140fd2694-1310350518.tcb.qcloud.la/thanks.png?sign=1f8e7c81d5468f1164e1054654a9b0f0&t=1658483671', // 分享图标 success: function () { // 设置成功 } }) //分享朋友圈 wx.updateTimelineShareData({ title: '测试标题', // 分享标题 link: 'http://test1001.wlphp.com/demo04/a.html?a=1&b=2', // 分享链接,该链接域名或路径必须与当前页面对应的公众号 JS 安全域名一致 imgUrl: 'https://636c-cloud1-8gsu5k8140fd2694-1310350518.tcb.qcloud.la/thanks.png?sign=1f8e7c81d5468f1164e1054654a9b0f0&t=1658483671', // 分享图标 success: function () { // 设置成功 console.log('分享成功') } }) return setTimeout(() => { wx.chooseImage({ count: 5, sizeType: ['original', 'compressed'], sourceType: ['album', 'camera'], success: function (res) { alert('已选择 ' + res.localIds.length + ' 张图片'); }, fail: function (err) { console.error(`chooseImage fail ${JSON.stringify(err)}`) }, }) wx.getLocation({ type: 'wgs84', // 默认为wgs84的 gps 坐标,如果要返回直接给 openLocation 用的火星坐标,可传入'gcj02' success: function (res) { var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90 var longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。 var speed = res.speed; // 速度,以米/每秒计 var accuracy = res.accuracy; // 位置精度 console.log(`getLocation ${JSON.stringify(res)}`) }, fail: err => { console.log(`getLocation fail ${JSON.stringify(err)}`) } }); }, 2000) }) wx.error(err => { console.error(`wx.error ${JSON.stringify(err)}`) }) } catch (e) { console.error(`error: ${e} ${e.stack}`) } } /** * 带登录态访问资源方的云开发资源,调用方式见文档,与小程序一致 */ window.accessResource = async () => { try { const c = window.instance await runWithLogs(() => c.database().collection('test').where({}).get(), `start db`, `db res`) } catch (e) { console.error('logs', `error: ${e}`) } } /** * 未登录模式下访问微信云开发的资源示例 */ window.accessResourceWithoutAuth = async () => { var c = new cloud.Cloud({ identityless: true, // 表示是未登录模式 resourceAppid: WX_RESOURCE_APPID, resourceEnv: WX_RESOURCE_ENVID, }) await c.init() await runWithLogs(() => c.database().collection('test').where({}).get(), `start db`, `db res`) } window.runWithLogs = async (fn, before, after) => { try { console.log(before) const res = await fn() console.log(`${after}: ${JSON.stringify(res)}`) } catch (e) { console.error(`error: ${e}`) } } window.payment = async () => { const orderid = document.querySelector('.input').value const money = document.querySelector('.input1').value const a = await instance.callFunction({ name: 'Pay1', data: { orderid: orderid, money: money } }) const payData = a.result.payment WeixinJSBridge.invoke( 'getBrandWCPayRequest', payData, function (res) { if (res.err_msg == "get_brand_wcpay_request:ok") { // 使用以上方式判断前端返回,微信团队郑重提示: //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。 } else if (res.err_msg == "get_brand_wcpay_request:fail") { console.log("支付失败") } else { console.log("取消支付") } } ) } </script> <style> .display-none { display: none; } .userinfo { display: flex; flex-direction: column; align-items: center; } .userinfo .avatar { width: max-content; box-shadow: inset 0 -3em 3em rgba(0, 0, 0, 0.1), 0 0 0 2px rgb(255, 255, 255), 0.3em 0.3em 1em rgba(0, 0, 0, 0.3); } .userinfo .name { border-bottom: 2px solid gray; padding: 0 5px 5px 5px; } a { list-style: none; } </style> </head> <body> <h2>云开发 Web 能力极简示例</h2> <p>请注意按照文档说明配置好,主要包括:</p> <p>1. 配置好公众号的授权回调域名及 JS 安全域名</p> <p>2. 配置好云开发授权关系(小程序授权云开发资源给公众号)</p> <p>3. 将代码中相应需要填入小程序/公众号 AppID 的地方进行相应改动</p> <p>4. 编写部署好微信云开发对应云环境的 cloudbase_auth 云函数和 echo 云函数</p> <p>5. 准备好后,页面加载后先点击登录,登录后再执行访问资源等其他操作,日志可在调试器查看</p> <div id="userinfo" class="userinfo" style="display: none"> <img class="avatar" /> <p class="name"></p> <p class="openid"></p> </div> <p><a href="javascript:;" onclick="doLogin()">登录(云开发公众号网页授权)</a></p> <p><a href="javascript:;" class="display-none" onclick="getUserInfo()">获取用户信息</a></p> <p><a href="javascript:;" class="display-none" onclick="useJSSDK()">使用 JSSDK</a></p> <p><a href="javascript:;" class="display-none" onclick="accessResource()">访问云资源</a></p> <p><a href="javascript:;" class="display-none" onclick="accessResourceWithoutAuth()">未登录模式下访问云资源</a></p> <p><input type="text" placeholder="请输入订单号" class="display-none input" name="orderid" value='' /></p> <script> var date = new Date(); // 通过以下三种方式获时间戳 time = date.getTime(); document.querySelector('.input').value = time </script> <p><input type="text" placeholder="请输入订单总价" class="display-none input1" name="money" value="1" /></p> <p><a href="javascript:;" class="display-none" onclick="payment()">微信支付</a></p> </body> </html>