云函数介绍:
1.当云函数被小程序端调用时,定义的代码会被放在Node.js运行环境中执行。
2.我们可以如在Node.js环境中使用JavaScript一样在云函数中进行网络请求等操作
3.在云函数中运行的代码拥有不受限的数据库读写权限和云文件读写权限。
4.云开发的云函数的独特优势在于与微信登录鉴权的无缝整合。当小程序端调用云函数时,云函数的传入参数中会被注入小程序端用户的openid,开发者无需校验openid的正确性因为微信已经完成了这部分鉴权,开发者可以直接使用该openid。
5.云函数中的时区为UTC+0,不是UTC+8,在云函数中使用时间时需特别注意。如果需要默认UTC+8,可以配置函数的环境变量,设置TZ为Asia/Shanghai
0、创建云开发环境
开发者工具创建后,可在project.config.json中查看或指定存放云函数目录
"cloudfunctionRoot": "cloudfunctions/", 在根目录cloudfunctions目录下存放
在开发者工具工具栏左侧,点击 “云开发” 按钮即可打开云控制台、根据提示开通云开发、创建云环境。
默认配额下可以创建两个环境,各个环境相互隔离,每个环境都包含独立的数据库实例、存储空间、云函数配置等资源。
每个环境都有唯一的环境 ID 标识,初始创建的环境自动成为默认环境。
AppID 首次开通云环境后,需等待大约10分钟方可正常使用云API,如尝试在小程序中调用云API则会报 cloud init error:{ errMsg: "invalid scope" } 的错误
1、创建云函数
会自动生成index.js文件,若无需手动生成
2、小程序端使用时初始化云函数
App({
onLaunch: function () {
if (!wx.cloud) {
console.error('请使用 2.2.3 或以上的基础库以使用云能力');
} else {
wx.cloud.init({
env: 'my-env-id', 填入环境 ID,环境 ID 可打开云控制台查看,如不填则使用默认环境(第一个创建的环境)
env:{ 对象可指定各个云功能的环境
database:'my-env-id',
storage:'my-env-id',
functions:'my-env-id'
}
traceUser: true, 是否在将用户访问记录到用户管理中,在控制台中可见
});
}
this.globalData = {};
}
});
跨账号环境共享或新建云开发操作实例
const a = new wx.cloud.Cloud({
resourceEnv: 'a', 环境ID,指定接下来调用 API 时访问哪个环境的云资源
traceUser: true, 是否在将用户访问记录到用户管理中,在控制台中可见
})
await a.init()
const res = await a.callFunction({
name: 'test',
data: {
...
},
})
3、云函数初始化
const cloud = require('wx-server-sdk')
cloud.init({
env: cloud.DYNAMIC_CURRENT_ENV 默认请求的云环境就是云函数当前所在的环境
env:'环境ID',
env:{
database:"环境ID",
storage:"环境ID",
functions:"环境ID",
default:"环境ID", 缺省时 API 默认环境配置
}
})
跨账号环境共享或新建云开发操作实例
exports.main = async (event) => {
const a = new cloud.Cloud({
resourceEnv: 'a',
timeout:15000 超时时间设置,默认15秒
})
await a.init()
const res = await a.callFunction({
name: 'test',
data: {
...
},
})
}
4、云函数语法
云函数内就相当于一个node,可进行node操作,如安装包等
右键云函数的文件夹,选择终端中打开,即可安装包
exports.main = (event, context, callback) => { 云函数入口文件,云函数被调用时实际执行的入口函数是index.js中导出的main方法
const { ENV, OPENID, APPID,UNIONID,OPEN_DATA_INFO } = cloud.getWXContext(); 云环境获取敏感信息,免鉴权
UNIONID仅在满足unionId获取条件时返回
OPEN_DATA_INFO通过云函数获取开放数据时,可用此校验入参中的开放数据是否来自微信后台
event代表调用云函数的函数中的data对象
context包含了此处调用的调用信息和运行状态,可以用它来了解服务运行的情况
callback为回调函数
return {
...
}
异步返回结果:(通过在云函数中返回一个Promise的方法来完成)
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(event.a + event.b)
}, 3000)
})
};
5、调用云函数
小程序中调用云函数:
回调方式:
wx.cloud.callFunction({
name:'云函数文件夹名',
data:{传入云函数的键值对}
success:function(res云函数的返回内容){
xx
},
fail,
completed
})
Promise方式:
wx.cloud.callFunction({
name:'云函数文件夹名',
data:{传入云函数的键值对}
当success、fail、complete都不存在时,为Promise调用方式
}).then(...).catch(...)
小程序端调云函数传递大数据可用的临时CDN:
如需传递大数据(建议128k以上时),可用此CDN方法标记需要传递的数据用这个方法可以避免大数据在云函数链路内的传输,提高大数据调用时的性能,同时避免触及调用数据的大小限制
wx.cloud.callFunction({
name: 'test',
data: {
strDemo: wx.cloud.CDN('some large string'), 传递字符串
filePathDemo: wx.cloud.CDN({ 当使用文件路径定义对象时,将在调用服务API时自动将相应文件路径对应的文件内容上传至 CDN 并转换成CDN URL
type: 'filePath', 定义对象的类型,必填filePath
filePath: 'xxxxxxxx',
}),
arrayBuffer:wx.cloud.CDN(ArrayBuffer)
},
})
.then(console.log)
.catch(console.error)
云函数中调用其他云函数:回调方式和小程序中一致
cloud.callFunction({
name: 'sum',
data: {
x: 1,
y: 2,
}
})
5.5、云函数中进行云调用(即调用服务端api)
(1)检查云调用的api是否支持
https://developers.weixin.qq.com/miniprogram/dev/api-backend/
(2)为云函数声明所需调用的接口
每个云函数需要声明其会使用到的接口,否则无法调用
云函数目录下的config.json,该配置有10分钟的缓存,如果更新后提示没有权限,稍等10分钟后再试
{
"permissions": {
"openapi": [
"templateMessage.send"
]
}
}
(3)云函数中调用
const cloud = require('wx-server-sdk')
cloud.init({
env: cloud.DYNAMIC_CURRENT_ENV
})
exports.main = async (event, context) => {
const result = await cloud.openapi.云调用接口(...)
return result;
}
6、调试云函数(在云函数界面,或右键云函数文件夹)
在正式的开发中,建议先在本地调试云函数通过后,再上传部署云函数进行正式测试,以保证线上发布的稳定性。
云端安装依赖(不上传node_modules文件夹)或全量上传(同时上传 node_modules 文件夹)
详见:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/guide/functions/local-debug.html
7、云函数顶层替换
接口如果涉及敏感数据(如wx.getWeRunData),接口的明文内容将不包含这些敏感数据,而是在返回的接口中包含对应敏感数据的cloudID字段,数据可以通过云函数获取或后端通过解密获取
调用云函数时,对传入的data参数,如果有顶层字段的值为通过wx.cloud.CloudID构造的CloudID
则调用云函数时,这些字段的值会被替换为cloudID对应的开放数据,一次调用最多可替换5个CloudID。
如:
方式一:
wx.cloud.callFunction({
name: 'myFunction',
data: {
weRunData: wx.cloud.CloudID('xxx'), 这个CloudID值到云函数端会被替换
obj: {
shareInfo: wx.cloud.CloudID('yyy'), 非顶层字段的CloudID不会被替换,会原样字符串展示
}
}
})
方式二:
const cloud = require('wx-server-sdk')
cloud.init({
env: cloud.DYNAMIC_CURRENT_ENV
})
exports.main = async (event, context) => {
const res = await cloud.getOpenData({
list: [CloudID字符串列表,...], list是一个 CloudID 字符串列表
})
return res.list
}
在云函数收到的event示例:
{
"weRunData": {
"cloudID": "xxx",
"data": {
"stepInfoList": [
{
"step": 5000,
"timestamp": 1554814312,
}
],
"watermark": {
"appid": "wx1111111111",
"timestamp": 1554815786
}
}
},
"obj": {
// 非顶层字段维持原样
"shareInfo": "yyy",
}
}
如果cloudID非法或过期,则在event中获取得到的将是一个有包含错误码、错误信息和原始cloudID的对象,过期cloudID换取结果示例:
{
"weRunData": {
"cloudID": "xxx",
"errCode": -601006,
"errMsg": "cloudID expired."
},
// ...
}
8、云函数灰度发布
详见:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/guide/functions/versions.html
9、云函数日志记录
const cloud = require('wx-server-sdk')
cloud.init({
env: cloud.DYNAMIC_CURRENT_ENV,
})
exports.main = async (event, context) => {
const wxContext = cloud.getWXContext()
const log = cloud.logger() 必须在exports.main中执行,否则不会生效。
log.info({ log | info | warn | error
name: 'xx',
cost: 10,
attributes: {
width: 100,
height: 200,
},
colors: ['red', 'blue'],
})
// 输出到日志记录中会有这么一条记录:
// {
// "level": "info",
// "name": "xx",
// "cost": "10",
// "attributes": "{ width: 100, height: 200 }",
// "colors": "[ "red", "blue" ]"
// ..., // 其他系统字段
// }
}
日志检索
详见:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/guide/functions/logservice.html
10、云函数定时触发器
在云函数的目录下,与index.js、package.json同级创建文件config.json
{
"triggers": [ 目前仅支持一个触发器,即数组只能填写一个,不可添加多个(未验证)
{
"name": "myTrigger", 最大支持60个字符,支持a-z,A-Z,0-9,-和_。必须以字母开头,且一个函数下不支持同名的多个定时触发器
"type": "timer",
"config": "0 0 2 1 * * *" 决定何时触发函数,触发器规则的时区为UTC+8
}
]
}
config中自定义标准的cron
第一位 第二位 第三位 第四位 第五位 第六位 第七位
秒 分钟 小时 日 月 星期 年
通配符:
,(逗号) 代表取用逗号隔开的字符的并集。例如:在“小时”字段中1,2,3表示1点、2点和3点
-(破折号) 包含指定范围的所有值。例如:在“日”字段中,1-15包含指定月份的1号到15号
*(星号) 表示所有值。在“小时”字段中,*表示每个小时
/(正斜杠) 指定增量。在“分钟”字段中,输入1/10以指定从第一分钟开始的每隔十分钟重复。例如,第11分钟、第21分钟和第31分钟,依此类推
示例:
*/5 * * * * * * 表示每5秒触发一次
0 0 2 1 * * * 表示在每月的1日的凌晨2点触发
0 15 10 * * MON-FRI * 表示在周一到周五每天上午10:15触发
0 0 10,14,16 * * * * 表示在每天上午10点,下午2点,4点触发
0 */30 9-17 * * * * 表示在每天上午9点到下午5点内每半小时触发
0 0 12 * * WED * 表示在每个星期三中午12点触发
11、云函数安全访问
config.json(未验证,文档未给出)中:
{
"*": { * 为通配符,表示对所有函数适用
"invoke": "auth != null"
invoke:表示调用权限控制
auth:包含鉴权信息,如果是未登录模式,则auth == null
},
"function1": { 具体函数名,该规则优先级会高于通配符
"invoke": true 表示允许所有来源调用,包括未登录用户
}
}
代码示例:
云函数文件夹:
'use strict';
// 次文件相当于一个模块,可进行node操作
//右键文件夹,选择终端中打开,即可安装包
//node导包方式
let axios=require('axios');
let httpUrl ="https://api.apiopen.top/getJoke"
//url参数设置
// let options1={
// page:1,
// count:10,
// type:'text'
// }
// let options2= {
// page: 1,
// count: 10,
// type: 'image'
// }
// let options3 = {
// page: 1,
// count: 10,
// type: 'video'
// }
exports.main = async (event, context) => {
let result=await axios.get(httpUrl,{params:event})
console.log("Hello World")
//调用云函数中的data对象
console.log(event)
//本地服务器的信息
console.log(context)
return result.data
};
js中调用云函数:
onLoad: function (options) {
wx.cloud.callFunction({
name: 'duanzi',
//传入的数据
data: {
page: 1,
count: 10,
type: 'image'
},
//成功回调,参数为云函数中的返回内容
success:function(res)
{
console.log(res);
}
})
}