您现在的位置是:网站首页> 小程序设计
小程序云开发技术收集
- 小程序设计
- 2026-11-03
- 61人已阅读
小程序云开发技术收集
***小程序云开发要区分云函数和其他能力(数据库、存储等)***

***使用 Uniapp + UniCloud 云开发微信小程序***
小程序请求不备案不要HTTPS方法(云函数使用http请求其他IP数据)
uniapp实现如何使用微信小程序云开发技术实现数据存储和实时通信
基础操作
云数据库权限在哪儿设置(该设置值对小程序端直接操作库有效)
### 入口(两个方式,效果一样)
1. **微信开发者工具里打开**
开发者工具顶部 → 点【云开发】按钮,打开云开发控制台 → 【数据库】→【集合管理】
选中你要设置的**集合(表)** → 点【数据权限】(安全规则)腾讯云开发...
2. **网页版云开发控制台(cloudbase)**
登录 [cloudbase.tencent.com](https://cloudbase.tencent.com),进入对应环境 → 数据库 → 集合,同样点【数据权限】
> ⚠️ 重点:**权限是按【集合】单独设置的,不是整个数据库统一一个权限**,每个集合独立安全规则微信开放社...
### 里面两种模式
- 简易预设(4 个单选)
- 仅创建者可读写(最常用,适合个人笔记、收藏)
- 所有用户可读,仅创建者可写
- 所有用户可读,仅管理员可写
- 仅管理员可读写(小程序前端完全不能操作这个集合,只能云函数 / 控制台读写)
- 【自定义安全规则】→ 写 JSON,精细控制 read /create/update /delete
```
{
"read": "auth.openid == resource.data.owner",
"write": "auth.openid == resource.data.owner"
}
```
> `auth.openid`:云端校验出来的登录身份,劫持不了;`resource` 代表这条数据库记录本身腾讯云开发
`auth.openid` = **当前登录用户的身份(云端拿到,可信)**
`resource.data.owner` = **这条数据库记录里面 owner 字段存的值(你自己存进去的那个 openid)**
### 非常重要的提醒
✅ **安全规则只限制【小程序前端直接调用 db】的请求!**
✅ **云函数读写数据库,不受这个集合安全规则限制(云函数是服务端身份,默认拥有全权限)**
❌ 很多人踩坑:集合设置了仅管理员读写,以为云函数也读不到,结果云函数照样随便读写。
## 式一:小程序前端直接操作数据库(wx.cloud.database)
⚠️ 风险提示:适合简单场景;虽然安全规则会拦越权,但 create 依赖 `request.data.owner`,理论上用户可以尝试篡改 owner,只是规则校验不匹配就报错。重要业务优先云函数。
```
// pages/index/index.js
const db = wx.cloud.database()
Page({
async onAddNote() {
// 获取当前登录openid(前端拿到的,不要在核心业务信任它,这里只是给owner赋值)
const { openid } = await wx.cloud.getOpenId()
try {
const res = await db.collection('demo_note').add({
data: {
title: '前端直接新增笔记',
content: '这条是前端直写数据库',
owner: openid,
createTime: db.serverDate() // 服务端时间
}
})
console.log('新增成功 _id:', res._id)
} catch (err) {
console.error('新增失败', err)
}
},
async onQueryNote() {
const { openid } = await wx.cloud.getOpenId()
try {
// 前端where只是过滤展示,真正权限屏障是安全规则
const res = await db.collection('demo_note')
.where({
owner: openid
})
.get()
console.log('查询结果', res.data)
} catch (err) {
console.error('查询失败', err)
}
},
async onUpdateNote() {
const _id = "你查到的文档_id"
try {
await db.collection('demo_note').doc(_id).update({
data: {
content: '前端直接修改内容'
}
})
console.log('更新成功')
} catch (err) {
console.error('更新失败', err)
}
},
async onDeleteNote() {
const _id = "你查到的文档_id"
try {
await db.collection('demo_note').doc(_id).remove()
console.log('删除成功')
} catch (err) {
console.error('删除失败', err)
}
}
})
```
---
## 方式二:云函数操作数据库(推荐,更安全)
### 1. 云函数端代码(函数名:`operateNote`)
> 重点:`owner` 在云函数内部从上下文取出,**前端不能传 owner**,杜绝伪造归属。
```
// cloudfunctions/operateNote/index.js
const cloud = require('wx-server-sdk')
cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV })
const db = cloud.database()
exports.main = async (event, context) => {
const { openid } = cloud.getWXContext()
const action = event.action // add / query / update / remove
try {
if (action === 'add') {
// 只接收业务字段,owner由后端自己注入
const { title, content } = event
const res = await db.collection('demo_note').add({
data: {
title,
content,
owner: openid,
createTime: db.serverDate()
}
})
return { code: 0, msg: '新增成功', data: res }
}
if (action === 'query') {
const res = await db.collection('demo_note')
.where({ owner: openid })
.get()
return { code: 0, msg: '查询成功', data: res.data }
}
if (action === 'update') {
const { _id, content } = event
await db.collection('demo_note').doc(_id).update({
data: { content }
})
return { code: 0, msg: '更新成功' }
}
if (action === 'remove') {
const { _id } = event
await db.collection('demo_note').doc(_id).remove()
return { code: 0, msg: '删除成功' }
}
return { code: -1, msg: '未知action' }
} catch (e) {
return { code: -99, msg: '操作失败', err: e }
}
}
```
### 2. 小程序前端调用云函数代码
前端只传业务内容,**不传递 openid、owner**:
```
// pages/index/index.js
Page({
// 新增
async addByCloudFunc() {
const res = await wx.cloud.callFunction({
name: 'operateNote',
data: {
action: 'add',
title: '云函数新增笔记',
content: 'owner在云函数内部自动赋值,前端无法篡改'
}
})
console.log('云函数新增返回:', res.result)
},
// 查询
async queryByCloudFunc() {
const res = await wx.cloud.callFunction({
name: 'operateNote',
data: { action: 'query' }
})
console.log('云函数查询结果:', res.result.data)
},
// 修改
async updateByCloudFunc() {
const res = await wx.cloud.callFunction({
name: 'operateNote',
data: {
action: 'update',
_id: '目标文档_id',
content: '云函数修改后的内容'
}
})
console.log(res.result)
},
// 删除
async delByCloudFunc() {
const res = await wx.cloud.callFunction({
name: 'operateNote',
data: {
action: 'remove',
_id: '目标文档_id'
}
})
console.log(res.result)
}
})
```
---
## 关键对比小结
1. 前端直写:
- ✅ 代码简单,不用上传云函数
- ❌ owner 由前端提交,必须靠安全规则拦截伪造
2. 云函数方案:
- ✅ openid/owner 在服务端上下文获取,前端无法篡改,最稳
- ✅ 可以加更多校验(长度、敏感词、库存、日志)
- ❌ 需要维护、上传部署云函数
云函数里发 HTTP 请求(相当于 ajax),**解决小程序前端跨域、密钥不能放前端的问题**。
推荐用 `axios`,简单好用;云函数是 node 环境,需要先装依赖。
> 函数名:`httpProxy`
## 1、云函数目录 package.json
```
{
"dependencies": {
"wx-server-sdk": "~2.6.3",
"axios": "^1.6.0"
}
}
```
安装命令(在云函数文件夹内执行)
```
npm install --production
```
> 上传的时候右键云函数 → **上传并部署:云端安装依赖**
## 2、云函数 index.js(GET + POST 通用代理示例)
```
const cloud = require('wx-server-sdk')
const axios = require('axios')
cloud.init({
env: cloud.DYNAMIC_CURRENT_ENV
})
exports.main = async (event, context) => {
const { openid } = cloud.getWXContext()
// 入参
const { url, method = "GET", body, headers = {} } = event
try {
const res = await axios({
url,
method,
headers: {
"Content-Type": "application/json",
...headers
},
data: body, // POST/PUT 的 body
timeout: 8000 // 超时时间,防止云函数卡死
})
return {
code: 0,
msg: "ok",
status: res.status,
data: res.data
}
} catch (err) {
console.error('第三方接口请求失败:', err.message, err.response?.data)
return {
code: -1,
msg: err.message,
status: err.response?.status,
data: err.response?.data
}
}
}
```
## 3、小程序前端调用这个云函数
```
// pages/index/index.js
Page({
// GET 例子
async reqGet() {
const res = await wx.cloud.callFunction({
name: 'httpProxy',
data: {
method: 'GET',
url: 'https://httpbin.org/get?name=test'
}
})
console.log('GET结果:', res.result)
},
// POST json例子(最常用,对接第三方api)
async reqPost() {
const res = await wx.cloud.callFunction({
name: 'httpProxy',
data: {
method: 'POST',
url: 'https://httpbin.org/post',
body: {
title: "测试标题",
content: "测试内容"
}
}
})
console.log('POST结果:', res.result)
}
})
```
## 4、重要避坑(高频踩坑点)
1. ✅ **密钥、token、apikey 全部写在云函数内部,不要从前端传进来**
安全写法示例:
```
const API_KEY = 'xxxx' // 写在云函数里,或者放到云函数【环境变量】
const res = await axios.get(url, {
headers: { Authorization: API_KEY }
})
```
2. ✅ 云函数**没有域名白名单限制**(和小程序前端不一样!),只要公网 HTTPS 接口都能请求
3. ⚠️ 超时:云函数默认超时 20s,axios 建议设置 timeout,避免占用计费时间
4. ⚠️ 不要做成无限制通用代理(前端随便传 url),会被滥用爬虫;**生产环境建议白名单判断 url**
```
// 简单url白名单
const allowHost = ['httpbin.org', 'xxx.api.com']
const host = new URL(url).hostname
if (!allowHost.includes(host)) {
return {code:-99, msg:'不允许访问该域名'}
}
```
5. ⚠️ 云函数有**流量和调用次数计费**,高频调用第三方接口注意成本
## 5、如果你不想装 axios(node 原生 http/https)
原生内置模块,不用装包,适合简单 GET:
```
const https = require('https')
exports.main = async (event) => {
return new Promise((resolve, reject) => {
https.get('https://httpbin.org/get', (resp) => {
let data = ''
resp.on('data', chunk=>data+=chunk)
resp.on('end', ()=>resolve({code:0, data:JSON.parse(data)}))
}).on('error', e=>reject(e.message))
})
}
```
## 6、结合你前面的业务:云函数里调第三方,再写入库
```
// 云函数内逻辑片段
const apiRes = await axios.post("https://xxx/api", {content:event.content})
// 拿到第三方返回结果,存入云数据库
await db.collection('api_log').add({
data:{
openid,
result: apiRes.data,
createTime: db.serverDate()
}
})
```
上一篇:小程序同行者