您现在的位置是:网站首页> 小程序设计

小程序云开发技术收集

摘要

小程序云开发技术收集

***小程序云开发要区分云函数和其他能力(数据库、存储等)***

1.jpg


小程序云开发帮助文档

***使用 Uniapp + UniCloud 云开发微信小程序***

***微信原生云开发教程***

使用 Uniapp + UniCloud 云开发微信小程序

小程序请求不备案不要HTTPS方法(云函数使用http请求其他IP数据)

uniapp实现如何使用微信小程序云开发技术实现数据存储和实时通信


基础操作

云数据库权限在哪儿设置(该设置值对小程序端直接操作库有效)

小程序前端和云函数操作数据库

云函数ajax调用第三方接口例子







云数据库权限在哪儿设置

### 入口(两个方式,效果一样)

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 在服务端上下文获取,前端无法篡改,最稳

   - ✅ 可以加更多校验(长度、敏感词、库存、日志)

   - ❌ 需要维护、上传部署云函数


云函数ajax调用第三方接口例子

云函数里发 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()

  }

})

```



















上一篇:小程序同行者

Top