# 公众号H5-访问云托管服务

公众号H5调用,是指在公众号登录状态下进行的调用。如果公众号未登录则和普通网页一样,没有微信用户体系。

公众号登录需要遵守公众号 - 网页授权,目前情况下只有 已经微信认证的服务号 才可以完成下述登录鉴权流程。

微信云托管环境需要满足如下两个条件任何一种:

  1. 微信云托管环境隶属于公众号云托管账号,也就是在控制台登录的是公众号
  2. 微信云托管环境被共享给目标公众号(资源复用模式)

其他不符合条件的账号无法通过本文档,请尝试普通网页调用方式

另外需要注意,使用此方案实施登录,推荐前端页面放置在静态资源存储或者云开发的静态网站托管上;目前云托管服务里动态服务提供页面还未自动支持,表现是 Cannot GET /__wx__/oauth

如果出现Cannot GET /__wx__/oauth,可以在服务内(云托管服务或自有服务器)配置转发规则,转发规则如下:
https://domain/__wx__/xxx -> https://servicewechat.com/wxa-qbase/xxx

location /__wx__/ {
    proxy_pass  https://servicewechat.com/wxa-qbase/;
}

# 基本使用

首先,在网页中引入如下3个 JS 文件

# 微信公众号SDK,用于使用前端公众号接口
https://res.wx.qq.com/open/js/jweixin-1.6.0.js

# 微信云服务SDK,用于调用微信云服务资源
https://web-9gikcbug35bad3a8-1304825656.tcloudbaseapp.com/sdk/1.3.0/cloud.js

# 封装的登录授权模块,可下载到本地按需修改
https://web-9gikcbug35bad3a8-1304825656.tcloudbaseapp.com/sdk/1.3.0/login_auth.js

然后在 js 中使用如下代码:

// 使用登录模块,传入初始化信息
const init_result = window.cloudbaseLogin.init({
  appid: 'wxaa01testenvid99',           //公众号appid,将以此 appid 名义进行请求
  resourceAppid: 'wxaa01testenvid99',   //公众号appid,或者环境共享下资源方微信账号
  resourceEnv: 'prod-testenvid',        //资源方微信云托管环境
  scope: 'snsapi_base'                  //登录方式:snsapi_userinfo、snsapi_base
})
// 如果云服务 SDK 和信息都就位,则初始化成功,init_result=ture
if (init_result) {
  // 登录模块将按照配置检查登录,如未登录则会路由刷新页面,直至得到登录 token 检查通过
  const do_result = window.cloudbaseLogin.doLogin().then(async res => {
    window.app = res.info // res.info 返回云服务 SDK 的可操作函数对象,将其放置全局

    const result = await window.app.callContainer({
      path: '/xxx', // 填入业务自定义路径和参数,根目录,就是 / 
      method: 'POST', // 按照自己的业务开发,选择对应的方法
      header: {
        'X-WX-SERVICE': 'xxx', // xxx中填入服务名称(微信云托管 - 服务管理 - 服务列表 - 服务名称)
      }
      // 其余参数同 wx.request
    })

    // 登录成功后,可以使用如下方法获取公众号接口签名,自行config
    const signature = await window.app.getJSSDKSignature({
      url: window.location.href // 需要传入当前网址
    })
  })
}

如果你想深入了解 callContainer 的原理,建议阅读这篇文章

# 请求参数

callContainer 其他参数,直接参考 wx.request API,在这里列举常用参数:

属性 类型 默认值 必填 说明 最低版本
config.env string 云环境 ID
path string 开发者服务器接口地址
data string/object/ArrayBuffer 请求的参数
header Object 设置请求的 header,header 中不能设置 Referer。
content-type 默认为 application/json
timeout number 超时时间,单位为毫秒
method string GET HTTP 请求方法
dataType string json 返回的数据格式
responseType string text 响应的数据类型
success function 接口调用成功的回调函数
fail function 接口调用失败的回调函数
complete function 接口调用结束的回调函数(调用成功、失败都会执行)

如果希望 wx.cloud.container 返回 Promise,请勿传 success, fail 和 complete

# object.method 的合法值

说明 最低版本
OPTIONS HTTP 请求 OPTIONS
GET HTTP 请求 GET
HEAD HTTP 请求 HEAD
POST HTTP 请求 POST
PUT HTTP 请求 PUT
DELETE HTTP 请求 DELETE
TRACE HTTP 请求 TRACE
CONNECT HTTP 请求 CONNECT

# object.dataType 的合法值

说明 最低版本
json 返回的数据为 JSON,返回后会对返回的数据进行一次 JSON.parse
其他 不对返回的内容进行 JSON.parse

# object.responseType 的合法值

说明 最低版本
text 响应的数据为文本
arraybuffer 响应的数据为 ArrayBuffer

# 示例代码

<script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
<script src="https://web-9gikcbug35bad3a8-1304825656.tcloudbaseapp.com/sdk/1.3.0/cloud.js" charset="utf-8"></script>
<script src="https://web-9gikcbug35bad3a8-1304825656.tcloudbaseapp.com/sdk/1.3.0/login_auth.js" charset="utf-8"></script>
<script>
  window.onload = async function () {
    const init_result = window.cloudbaseLogin.init({
      appid: 'wxaa01testenvid99',           //公众号appid,将以此 appid 名义进行请求
      resourceAppid: 'wxaa01testenvid99',   //公众号appid,或者环境共享下资源方微信账号
      resourceEnv: 'prod-testenvid',        //资源方微信云托管环境
      scope: 'snsapi_base'                  //登录方式:snsapi_userinfo、snsapi_base
    })
    // 如果云服务 SDK 和信息都就位,则初始化成功,init_result=ture
    if (init_result) {
      // 登录模块将按照配置检查登录,如未登录则会路由刷新页面,直至得到登录 token 检查通过
      const do_result = window.cloudbaseLogin.doLogin().then(async res => {
        window.app = res.info // res.info 返回云服务 SDK 的可操作函数对象,将其放置全局

        const result = await window.app.callContainer({
          path: '/xxx', // 填入业务自定义路径和参数,根目录,就是 / 
          method: 'POST', // 按照自己的业务开发,选择对应的方法
          header: {
            'X-WX-SERVICE': 'xxx', // xxx中填入服务名称(微信云托管 - 服务管理 - 服务列表 - 服务名称)
          }
          // 其余参数同 wx.request
        })
        console.log(result)
        // 登录成功后,可以使用如下方法获取公众号接口签名,自行config
        const signature = await window.app.getJSSDKSignature({
          url: window.location.href // 需要传入当前网址
        })
        console.log(signature)
      })
    }
    else {
      alert('没有引入cloud-sdk')
    }
  }
</script>