-

云开发的环境还可以开发网站应用,包括普通的 PC 网页或者公众号中的网页等,在开发过程中即便需要后台服务也无需搭建服务器,可以直接使用云开发提供的云端能力。开发者无需关心具体的后台资源及运维,只需使用平台提供的 API 进行核心业务开发,即可实现产品快速上线和迭代。

一、创建初始项目

在前面我们已经用Cloudbase Cli工具在电脑本地用Cloudbase init创建了一个云开发项目,以及开通了静态网站托管,那我们应该如何在静态的网页里初始化云开发呢?

1、项目文件结构

使用编辑器比如 Visual Studio Code,打开前面创建好的项目文件夹tcbweb,然后使用VS Code来新建一个public文件夹,并在public文件夹里面新建

  • index.html;

  • js文件夹,js文件夹里再新建一个main.js;

  • css文件夹,css文件夹里再新建一个style.css;

  • assert文件夹,assert文件夹里主要用于存放图片等资源;

最终文件夹的目录结构如下,一个清晰的项目文件结构便于我们有序的开发管理:

. 
├── _gitignore
├── functions // 云函数目录
│   └── app
│       └── index.js
├── public // 用于存放应用程序的静态文件
│   └── index.html 
│   └── js
│       └── main.js
│   └── css
│       └── style.css
│   └── assert
└── cloudbaserc.js // 项目配置文件

>在前面我们已经介绍过电脑的终端,Visual Studio Code也有终端,也可以在这个终端里面进行终端的命令行操作,和电脑的终端略有不同,大家也可以根据习惯自行选择。

2、在网页中引入Web端SDK

然后使用VS Code打开index.html文件,VS Code编辑器内置一套emmet语法,可以大大提高我们书写HTML代码的效率,在index.html里输入一个英文状态下的感叹号!,之后按一下tab键,就会出现以下代码,并修改一下title和body标签里面的内容:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Web端云开发</title>
</head>
<body>
  Web端云开发页面内容
</body>
</html>

然后将head标签里添加如下内容,把云开发web端SDK也就是tcb.js添加到Web应用中:

<head>
  <!-- 省略-->
  <script src="https://imgcache.qq.com/qcloud/tcbjs/1.7.0/tcb.js" rel="external nofollow" ></script>
  <script src="./js/main.js"></script>
</head>

>注意上面的版本号1.7.0,这个不一定是最新的,建议tcb-js-sdk npm包地址获取最新的版本号,尤其是需要使用新功能的时候,要注意修改版本号。我们还可以通过npm install --save tcb-js-sdk@latest引入npm包tcb-js-sdk的方式来下载最新版的Web端SDK,而在模块化开发时用const tcb = require("tcb-js-sdk");将Web端SDK引入到项目中,这里就不多介绍啦。

3、初始化Web端环境

使用VS Code打开js文件夹下main.js文件,在里面输入以下代码就可以完成云开发环境的初始化,和小程序云开发一样,要调用云开发环境里的资源,就需要进行初始化,init 用于设置调用云函数、数据库、文件存储时要访问的环境。

  const app = tcb.init({
    env: '你的环境ID'  // 此处填入你的环境ID
  });

>我们知道在项目根目录下的配置文件cloudbaserc.js或cloudbaserc.json里也需要填入环境ID,这个配置文件主要用于项目管理,这个和初始化Web端环境是有一定的区别的哦,留意一下。

也就是说我们要初始化云开发能力,一是要引入Web端SDK tcb.js文件,二是要初始化Web端的环境,这两个是必不可少的哦,引入这两个之后,云开发能力就算完成初始化了。

二、本地调试与云端调试Web端云开发

要在本地电脑里调试Web端云开发,除了前面已经做过的在电脑里安装Nodejs环境、安装Cloudbase Cli工具、初始化云开发项目之外,还需要执行以下操作。

使用小程序云开发的账号登录到腾讯云云开发控制台,也就是登录时选择微信公众号登录,然后用小程序云开发管理员的微信扫码,在云开发控制台选择其中一个环境,进入到该环境的管理页,点击环境-环境设置菜单,选择登录方式标签页,然后:

1、开启匿名登录

登录方式里可以选择启动匿名登录,匿名登录有点类似于游戏里的游客访问模式,用户不需要注册就可以获取并存储数据,这种方式比较方便我们进行本地调试。

>每个设备同时只存在一个匿名用户,并且此用户永不过期(如果用户手动清除了设备或浏览器的本地数据,那么匿名用户的数据便会被同步清除,再次调用匿名登录API会产生一个新的匿名用户)。每个环境的匿名用户数量不超过1000万个。

打开前面创建的main.js文件,在环境初始化后面添加如下代码,实现匿名登录的功能。window.onload类似于小程序生命周期的onLoad生命周期函数,当包括样式、图像和其他资源的页面被全部加载时,window 对象上的 load 事件就会被触发。

window.onload = function(){
  app.auth({
      persistence: 'session' //在窗口关闭时清除身份验证状态
  })
    .anonymousAuthProvider() 
    .signIn()   //AnonymousAuthProvider.signIn() 匿名登录云开发
    .then(() => {
        console.log("登录成功") //登录成功
    }).catch(err => {
        console.log("登录失败",err) //登录失败
    })
    env: 'xly-xrlur'  // 此处填入你的环境ID
  });

2、添加安全域名

WEB安全域名处把 localhost:5000加入到安全域名的白名单中,这样这个域名下的页面才可以使用 SDK 访问到云开发的服务。如果你希望通过localhost的其他端口或域名地址来访问你的静态托管网站,你需要将这些它们都添加到安全域名的列表里面。

3、开启本地开发环境

打开终端,我们先全局安装依赖包serve(注意前面说过的安装权限解决方案,Mac电脑命令前加sudo,Windows要用管理员身份打开终端):

npm install -g serve

然后在项目根目录(注意前面说过的cloudbaserc.js所在的目录即为根目录)执行以下命令运行serve,即可打开一个本地静态服务器:

npx serve

成功后就会显示服务开启,以及可以在本地电脑的浏览器访问的localhost端口地址,以及ip地址。在浏览器里输入http://localhost:5000/public/就能打开index.html了。打开浏览器的开发者工具,在Console标签页看到登录成功的log,就表示匿名登录成功啦

>建议使用Chrome浏览器,在index.html页面空白处鼠标右键点击”审查元素”(MacBook 为”检查”),我们就可以打开Chrome的开发者工具,在Console标签页我们就可以调试代码。

为了调试方便,我们可以不要关闭npx serve的终端窗口,要执行其他任务可以重新开一个终端窗口。当我们更新public文件夹下的index.html、main.js文件时,直接刷新浏览器里的页面即可。

4、部署本地文件到静态托管

我们再开一个终端窗口,然后通过cd 命令进入到项目根目录,之后在终端输入以下命令,将public文件夹下面的所有文件上传到静态托管网站的文件夹内,比如上传到web文件夹到环境id为xly-xrlur的环境里:

cloudbase hosting:deploy ./public web -e xly-xrlur

然后我们就可以在浏览器通过打开静态托管网站的二级域名/web你的域名/web访问到这个页面了,同样可以使用浏览器的开发者工具的控制台查看页面的打印日志。

>调用Web端SDK并不局限于云开发自带的静态托管服务,我们也可以使用Github Pages等其他静态托管服务,也可以是传统开发的web页,也就是说只要是web也引入sdk,并添加安全域名等之后,也能使用云开发的服务。

三、创建并调用云函数

1、云函数的创建与部署

Web端云开发不仅可以调用你在小程序云开发里创建的云函数,我们也可以在本地创建云函数并部署到云开发环境里供Web端和小程序端来调用,也就是云开发环境里的云函数是Web端和小程序端共用的,小程序端怎么创建并部署云函数大家应该比较熟悉,web端使用vscode来创建并部署云函数和使用微信开发者工具是一样的道理。

2、本地云函数目录结构

我们可以在web端云开发项目根目录里的functions文件夹下面建和小程序云开发云函数根目录一样的文件夹表示为云函数目录,以及一样新建三个文件并copy里面的内容(每次创建一个云函数的时候都这么做),比如我们新建一个webtest的云函数,它的目录结构如下:

├── _gitignore
├── functions // 云函数根目录
│   └── app   //app云函数目录
│       └── index.js
│       └── config.json 
│       └── package.json
│   └── webtest  //webtest云函数目录
│       └── index.js       //主体结构和小程序云开发云函数里的index.js一样
│       └── config.json    //copy小程序云开发云函数里的config.json
│       └── package.json  //copy小程序云开发云函数里的package.json
├── public // 用于存放应用程序的静态文件
│   └── index.html 
│   └── js
│       └── main.js
│   └── css
│       └── style.css
│   └── assert
└── cloudbaserc.js // 项目配置文件

在index.js里我们可以输入以下代码,引入服务端sdk,初始化服务端的环境,以及在main函数里返回数据:

const tcb = require('@cloudbase/node-sdk')
const app = tcb.init({
  env: '你的环境ID'
})
const auth = app.auth()
exports.main = async (event, context) => {
   const ip = auth.getClientIP()  //获取客户端ip
   const {
    openId, //微信openId,非微信授权登录则空
    appId, //微信appId,非微信授权登录则空
    uid, //用户唯一ID
    customUserId //开发者自定义的用户唯一id,非自定义登录则空
  } = auth.getUserInfo()
  return {"event对象":event,
  "context对象":context,
  "客户端ip":ip,
  "openId":openId,
  "appId":appId,
  "uid":uid,
  "customUserId":customUserId
  }
}

>web端创建的云函数这里,我们既可以只用 Web端SDK @cloudbase/node-sdk,也可以沿用小程序云开发的写法,使用wx-server-sdk,如果是跨端开发建议后者。

3、安装依赖并部署上传云函数

然后使用终端打开云函数目录,使用npm install来安装依赖package.json的依赖之后,在cloudbaserc.js的配置文件的functions里添加webtest云函数的配置,比如:

{
    name: "webtest",
    timeout: 5,
    envVariables: {},
    runtime: "Nodejs10.15",
    handler: "index.main"
},

使用Cloudbase Cli工具将云函数部署上传到云端:

cloudbase functions:deploy webtest

这里有几个需要注意一下,小程序端云开发与Web端云开发的相同与不同之处:

  • 如果你的云函数不需要给小程序使用而只在web端使用,你可以只引入@cloudbase/node-sdk,而如果要在小程序端使用,你引入的wx-server-sdk,@cloudbase/node-sdk是云开发的服务端sdk,wx-server-sdk是小程序云开发的SDK;所以最好是用变量tcb表示引入@cloudbase/node-sdk,变量cloud表示wx-server-sdk;

  • Web端云开发的云函数和小程序云开发的使用方法大致相同,也要注意web端/小程序端和服务端的不同用法与权限;

  • 将Web端云函数部署上传到小程序创建的云开发环境,在小程序开发者工具的云开发控制台是可以看到该云函数的,同时调用这个云函数的日志也在云开发控制台的日志里看到。

  • 如果没有在cloudbaserc.js配置,会显示未找到函数发布配置,是否使用默认配置(仅适用于 Node.js 云函数)的提示

4、web端调用云函数

在web端调用云函数,则是使用web端sdk,也就是tcb-js-sdk模块或前面引入tcb.js文件,我们可以在main.js文件里将函数的调用写到app.auth()的回调函数里,当页面加载时匿名用户登录后,就能调用云函数

window.onload= function(){
  app.auth({
    persistence: 'session' //在窗口关闭时清除身份验证状态
  })
    .anonymousAuthProvider()
    .signIn()
    .then(() => {
      app.callFunction({
        name: 'webtest',
        data: { "name": "李东bbsky", "title": "杂役"}
        })
        .then((res) => {
          console.log(res)
        });
    }).catch(err => {
      console.log("登录失败",err)
    })

使用浏览器打开(或刷新页面)http://localhost:5000/public/index.html,然后在浏览器开发者工具的控制台就能看到本地调用云函数的结果啦。我们再执行以下命令将public的静态页面更新到静态存储,再来打开二级域名/web下的网页,在浏览器开发者工具的控制台也能调试代码啦:

cloudbase hosting:deploy ./public web -e xly-xrlur

通过打印我们可以了解到,web端上传的参数会在event对象里,且event对象会返回用户的userInfo,其中包含微信appId,而context对象则包含关于该云函数的一些信息。

>有了web端SDK,我们就能调用云开发环境里的云函数,而云函数也是可以调用云函数、可以对数据库、云存储进行增删改查,还能使用云调用(需要openid的云函数例外),因此我们也可以沿用小程序云开发的云函数的用法。我们也要留意使用CLoudbase Cli触发云函数,以及web端触发云函数和后面使用云接入的方式获取到的云函数的信息会有所不同。

四、web端操作数据库

和小程序触发事件处理函数一样,我们既可以使用通过页面的生命周期函数,也可以通过点击的方式,比如在web页面的标签上绑定事件处理函数来触发事件处理函数,来对云函数、数据库、云存储进行一系列的操作。

比如我们可以在public文件夹下的index.html<body>标签内输入以下代码,一个button标签里,绑定getData()事件处理程序,

<button onclick="getData()">点击获取数据</button>

然后在main.js里添加getData()事件处理函数,保存页面之后,点击button按钮就能触发事件处理程序,对数据发起请求,这里还是获取以前在小程序云开发创建的集合china:

function getData(){
  const db = app.database();
  const _ = db.command
  const $ = db.command.aggregate
  db.collection("china")
    .where({
      gdp: _.gt(3000)
    })
    .field({
      _id:false,
      city: true,
      province: true,
      gdp:true
    })
    .orderBy('gdp', 'desc')
    .skip(0)
    .limit(10)
    .get()
    .then(res => {
      console.log(res.data)
    })
    .catch(err => {
      console.error(err)
    })
}

无论是查询数据,还是对数据库的添加记录、删除数据以及指令、聚合等都和小程序云开发保持了很强的一致性,注意哦,数据库的实时推送也是和小程序端的用法一样。

>值得注意的是当匿名用户往数据库里添加数据时,云数据库也会默认生成_openid的字段,这个openid是临时的,在前面已经说过它的机制啦。

一、web端操作云存储

1、web端上传文件

和小程序云开发一样,要在前端上传文件,首先我们需要建一个上传文件的标签,在public文件夹下的index.html里再输入以下代码,我们只允许上传图片,并绑定

<input type="file" id="file" accept="image/*" onchange="uploadFile()">

然后我们继续在main.js里输入以下代码。被选择的文件以 HTMLInputElement.files 属性返回,它是一个包含一列 File 对象的 FileList 对象。FileList 的行为像一个数组,所以你可以检查 length 属性来获得已选择文件的数量。

function uploadFile() {
    const filetemp = document.getElementById("file").files[0]
    console.log("file对象",filetemp)  //打印文件对象
    const fileName = filetemp.name //从打印对象知道,这就是文件的名称
    app.uploadFile({
        filePath: filetemp,   //本地文件
        cloudPath: `tcb/${fileName}`,  //云存储的路径
        onUploadProgress: (progressEvent) => { //上传进度回调
          let percentCompleted = Math.round( 
            (progressEvent.loaded * 100) / progressEvent.total
            );
          console.log('上传进度: ' + percentCompleted, progressEvent);
        }
      }, function (err, res) {
          console.log({err,res})
    });
}

>注意,这个云存储的路径前面不要有/,也不能直接是根目录,否则会没有上传权限;尽管云存储可能并没有tcb这个文件夹,但是会自动创建。

2、web端删除文件

在public文件夹下的index.html里再输入以下代码,我们写一个绑定了deleteFile事件的button按钮:

 <button onclick="deleteFile()">删除文件</button>

然后我们继续在main.js里输入deleteFile事件处理函数,当点击按钮时删除云存储里指定fileID的文件:

async function deleteFile() {
  const result = await app.deleteFile({
    fileList: ['cloud://xly-xrlur.786c-xly-xrlur-1300446086/tcb/WX20200401-144620@2x.png']
  })
  result.fileList.forEach(item => {
    if (item.code === 'SUCCESS') {
      alert("文件删除成功")
    }
  })
}

云开发的登录还支持自定义登录、微信公众平台、微信开放平台登录,这个在后面会介绍。