评论

小程序环境共享入门/跨账号环境调用

跨账号环境调用、资源共享入门

先上文档:官方文档

一般碰到问题比较多的是怎么起步,

!important
为了方便讲清楚概念,我们称呼主账号(提供资源/函数的小程序)为【资源方】,要进行跨账号环境调用资源的账号为【调用方

(需小程序公共库 2.13.0 或以上)(需 wx-server-sdk 版本大于或等于 2.3.0)

  1. 确保要共享资源的两个小程序在同个主体下面
    例如同个公司、个人开发者等。

  2. 用微信开发者工具,打开【资源方】,点击头像右侧的云开发

  3. 点击云开发弹框右侧的设置

  4. 选择顶部tab栏目的拓展功能

  5. 点击环境共享的开通

  6. 点击添加共享,并输入【调用方】的appid,根据需求勾选权限并确认

  7. 用微信开发者工具,打开【调用方】

  8. 点击云开发确认可以看到【资源方】的云函数和云存储,如果这一步没看到共享的内容,返回确认前面的步骤

  9. 在【资源方】的云开发-设置-环境设置-环境名称处,创建开通按量计费(免费)的云开发环境。

配置部分非常繁琐,但是到这里就结束了。接下来是开发部分

【资源方】云函数部分改动的内容,入口

const cloud = require('wx-server-sdk')
cloud.init({
  env: cloud.DYNAMIC_CURRENT_ENV
})

// 云函数入口函数
exports.main = async (event, context) => {
  const wxContext = cloud.getWXContext()

  console.log(event)
  console.log(wxContext)
  // 跨账号调用时,由此拿到来源方小程序/公众号 AppID
  console.log(wxContext.FROM_APPID)
  // 跨账号调用时,由此拿到来源方小程序/公众号的用户 OpenID
  console.log(wxContext.FROM_OPENID)
  // 跨账号调用、且满足 unionid 获取条件时,由此拿到同主体下的用户 UnionID
  console.log(wxContext.FROM_UNIONID)

  return {
    errCode: 0,
    errMsg: '',
    auth: JSON.stringify({
      // 自定义安全规则
      // 在前端访问资源方数据库、云函数等资源时,资源方可以通过
      // 安全规则的 `auth.custom` 字段获取此对象的内容做校验,
      // 像这个示例就是资源方可以在安全规则中通过 `auth.custom.x` 获取
      x: 1,
    }),
  }
}

【调用方】云函数部分改动的内容

!important
这边前端建议对所有云函数入口做一个统一的路由,不要到处callFunction。
在统一路由那边,我一般是这样写在utils里,或者写到route.js里,这样你只要改一个地方,就可以修改整个小程序的所有请求

async function requestCloud(requestName, data) {
    wx.cloud.init({
      traceUser: true
    })
    let c1 = new wx.cloud.Cloud({
      // 资源方 AppID
      resourceAppid: 'wx5d8d765e252720eb',
      // 资源方环境 ID
      resourceEnv: 'production-rjntq',
    })

    await c1.init()

    return await c1.callFunction({
      name: requestName,
      data: data
    })
 }

如果是用promise的写法,就外面再包一层,举例,把上面的代码,加上下面的部分,塞到同一个新的function里,

return new Promise(function (resolve, reject) {
 requestCloud(requestName, data).then(res => {
 if (res.result.code == 0) {
     resolve(res.result.data)
     return
   } else {
     hideLoading()
     wx.showToast({
       title: res.result.msg,
       icon: 'none'
     })
     reject(res.result)
     return
   }
 }).catch(err => {
   reject(err)
   return
 })
})

纯前端的部分就结束了,这边遇到问题最多的是,没想到这玩意儿要初始化两次云函数,一次是自己的,一次是【资源方】的。

如果是【调用方】也有自己的后台,想要调用【资源方】的云函数,

const cloud = require('wx-server-sdk')

exports.main = async (event) => {
// 声明新的 cloud 实例
var c1 = new cloud.Cloud({
 // 资源方 AppID
 resourceAppid: 'wxe0e2656d74f0bff3',
 // 资源方环境 ID
 resourceEnv: 'test-f96b31',
})

// 跨账号调用,必须等待 init 完成
// init 过程中,资源方小程序对应环境下的 cloudbase_auth 函数会被调用,并需返回协议字段(见下)来确认允许访问、并可自定义安全规则
await c1.init()

// 完成后正常使用资源方的已授权的云资源
return c1.callFunction({
 name: '函数名',
 data: {},
})
}

好了,你再编译一下自己的【调用方】代码,应该就ok了。

我现在卡在怎么以【调用方】身份,在wxml中例如Image src里直接访问【资源方】的图片资源。按理说云开发面板上是可以看到的,以及也授权了,应该是可以直接打开才对,但是渲染层就是打不开。有发现的朋友麻烦联系我微信:SH-Yushi。十分感谢。

已经通过后台批量替换cloud前缀为https格式解决。
现在还剩如何直接操作【资源方】云数据库。保底方案是通过云函数绕过去

update by 2020-11-05
有人私聊我怎么直接访问资源方图片。
我把我批量替换的方法写下面,供后人参考

function changeImageUrl(imageUrl) {

  if (this.isEmpty(imageUrl)) {
    return
  }

  let la = 'cloud://production-rjntq.'
  let ra = '1302413556/'
  let start = imageUrl.indexOf(la)
  if (start < 0) {
    return imageUrl
  }
  let end = imageUrl.indexOf(ra) - 1
  let front = 'https://' + imageUrl.substring(la.length, end + ra.length) + '.tcb.qcloud.la'


  let back = imageUrl.substring(end + ra.length)

  return front + back
}

记得去云存储里面看一眼自己的图片,右键查看详情,查看下载地址,你的那串数字应该和我的肯定是不同的,到我封的方法里把数字替换成自己的。

这边的问题是,虽然小程序开放了跨资源调用,也在文档里说可以跨资源访问图片,但是开发组告诉我们暂时不支持直接调用cloud://的path。因此想到转成https。好在他们的格式都是固定的,所以可以批量替换。

这边有个小坑,在动手操作之前还是仔细看自己的图片存储目录,因为每个人的 文件目录层级不同,因此前缀格式会有略微差别。但是思路是一致的。

最后一次编辑于  2020-11-05  
点赞 2
收藏
评论

6 个评论

  • ノ故渊੭
    ノ故渊੭
    2020-11-04

    你好,我这边只要执行资源方初始化就莫名的报

    资源方已经开启共享并且可以在调用方查看到资源方的环境,所以排出配置问题。

    麻烦楼主帮忙看下导致的原因,谢谢

    2020-11-04
    赞同 1
    回复 2
    • 清水裕夏
      清水裕夏
      2020-11-05
      你这边的问题应该是资源方配置晚了,要在初始化自身cloud实例以后,再立刻初始化资源方cloud实例,然后用资源方的cloud实例去调用test。


      你的test云函数是写在资源方里的对吧?
      2020-11-05
      1
      回复
    • Siuhing
      Siuhing
      2022-02-21
      "你这边的问题应该是资源方配置晚了"——请问这个是什么意思?是指控制台的配置吗?还是代码里的初始化,我直接复制了楼主的代码,前面的都可以通过,就是一直提示『找不到对应的FunctionName』
      2022-02-21
      回复
  • 陈怀俊(业主我当家)
    陈怀俊(业主我当家)
    2021-03-23

    此贴说得比较到位,也是我经历过的坑,例如图片跨资源环境访问,函数跨资源环境访问,目前我正卡在调用方如何访问资源方的云数据库,这是普遍的数据库共享需求,请问哪位有经验的大侠麻烦解答下,有云开发深入研究的同行也可加我微信:13883166466,谢谢!

    2021-03-23
    赞同
    回复
  • 洞洞滨
    洞洞滨
    2021-03-03

    你好,我这边按照你说的走下去,函数调用通了,但是errCode: 48001 说我没有api的访问权限。。请问这个是哪里出了问题呀。我查了好多地方都没有解决方案。

    2021-03-03
    赞同
    回复 1
    • 清水裕夏
      清水裕夏
      2021-03-03
      检查前置步骤,两个小程序是否同个公司主体绑定。在开发工具的云环境配置里也查看一下是否已经关联。再检查cloud_auth鉴权做了没,要根据调用方的appid来做。大概率问题出在最后一步鉴权上
      2021-03-03
      回复
  • YL🌿
    YL🌿
    2020-12-10

    按照文档的来,报错 wx.cloud.Cloud is not a constructor ,怎么说不是一个构造器啊?

    2020-12-10
    赞同
    回复 1
    • 清水裕夏
      清水裕夏
      2021-01-15
      1.要先创建自己的云环境,再用自己创建的云环境去创建跨资源的云环境。所以先确保wx.cloud.init(),再去wx.cloud.Cloud(创建跨资源云环境通道)。2.你现在是同步调用,要改成异步。初始化云环境需要时间,你还没初始化好就在callFunction了。
      2021-01-15
      回复
  • 冬
    2020-12-10

    调用c1的callFuntion方法报这个错怎么整啊

    2020-12-10
    赞同
    回复 1
    • 清水裕夏
      清水裕夏
      2021-01-14
      你没有先初始化自己的云环境,就直接发起跨环境调用所以失败。
      async function requestCloud(requestName, data) {
          wx.cloud.init({
            traceUser: true
          })
          let c1 = new wx.cloud.Cloud({
            // 资源方 AppID
            resourceAppid: 'wx5d8d765e252720eb',
            // 资源方环境 ID
            resourceEnv: 'production-rjntq',
          })


          await c1.init()


          return await c1.callFunction({
            name: requestName,
            data: data
          })
       }
      2021-01-14
      回复
  • 起者王也
    起者王也
    2020-10-27

    我也想问为什么不能显示资源方的图片

    2020-10-27
    赞同
    回复 2
    • 清水裕夏
      清水裕夏
      2020-11-05
      问了腾讯云那边,目前跨资源调用不允许代码层面直接访问资源方的cloud path格式的图片资源,建议我们模仿在云存储页面,对应资源右键以后,查看详情,在右侧弹出的https:格式的path。
      我写了个方法你可以直接拿去用
      2020-11-05
      回复
    • 深蓝
      深蓝
      2023-05-18回复清水裕夏
      怎么解决呀?
      2023-05-18
      回复
登录 后发表内容