14.5 云接入与HTTP触发

云接入是云开发基于云函数之上为开发者提供的HTTP访问服务,开发者可以轻松使用 POST、PUT、GET、DELETE等方法通过 HTTP 请求访问到云开发环境内的全部资源,而不需要使用Web端 SDK。而且云接入天然支持跨域请求,将域名添加至Web 安全域名中,这个域名里的网页便可以跨域访问云接入。当使用云函数时,系统会自动预配TLS证书,因此我们可以通过安全连接调用云函数。

14.5.1 使用云接入访问云函数

给云函数启用云接入的方式非常简单,我们可以使用腾讯云云开发网页控制台以及Cloudbase Cli命令两种方式。

1、云开发控制台启动云接入

打开腾讯云云开发网页控制台的云函数菜单,然后点击HTTP触发标签,开启HTTP触发,云接入就启动啦,云接入的默认域名就是https://{你的环境id}.service.tcloudbase.com/

在前面我们已经上传了一个webtest的云函数(其他云函数也都可以的哦),点击进入webtest云函数的管理页,然后点击右上角的编辑,在HTTP 触发路径里输入/webtest(也可以是其他值),保存之后,在浏览器里打开以下链接(网页控制台直接就有链接)就可以访问云接入了:

https://{你的环境id}.service.tcloudbase.com/webtest

大家可以对比一下event、context对象与调用云函数返回的对象有什么不同。使用云接入调用云函数时,HTTP 请求会被转化为特殊的结构体,称之为集成请求,结构如下:

{ path: 'HTTP请求路径,如 /hello', httpMethod: 'HTTP请求方法,如 GET', headers: {HTTP请求头}, queryStringParameters: {HTTP请求的Query,键值对形式}, requestContext: {云开发相关信息}, body: 'HTTP请求体', isBase64Encoded: 'true or false,表示body是否为Base64编码' }

这里的queryStringParameters是HTTP请求的Query,我们可以在链接里传入一些参数,比如在访问云接入的链接里加一些参数:

https://xly-xrlur.service.tcloudbase.com/webtest?name=bbsky&location=shenzhen

2、使用Cloudbase Cli启动云接入

在前面我们已经了解到通过在终端输入cloudbase --help可以了解到Cloudbase Cli有哪些命令(尽管cloudbase是全局的,建议大家在云开发项目的根目录执行),我们可以看到关于云接入的命令有:

service:switch [options] 开启/关闭 HTTP Service 服务 service:auth:switch [options] 开启/关闭 HTTP Service 服务访问鉴权 service:create [options] 创建 HTTP Service service:delete [options] 删除 HTTP Service service:list [options] 获取 HTTP Service 列表 service:domain:bind [options] <domain> 绑定自定义 HTTP Service 域名 service:domain:unbind [options] <domain> 解绑自定义 HTTP Service 域名 service:domain:list [options] 查询自定义 HTTP Service 域名

由这些命令,我们可以在终端里输入以下命令来开启和关闭云接入,比如开启云开发环境id为xly-xrlur的云接入服务:

cloudbase service:switch -e xly-xrlur

而我们可以执行以下命令创建一条云接入路由,路径为 /webtest,指向的云函数为 webtest:

cloudbase service:create -p /webtest -f webtest

除了可以使用浏览器里打开云接入的链接,我们还可以使用cURL命令行来调用云接入,比如我们可以在终端输入以下命令:

curl https://xly-xrlur.service.tcloudbase.com/webtest

3、参数的传入与获取总结

我们有必要重新梳理一下一些参数的传入与获取相关的知识,我们往云函数里传入参数的方式有调用云函数时传入参数、访问云接入链接时传入参数以及配置云函数环境时添加配置信息,那这三种方法又是如何获取这些参数呢?(还有一种是通过require模块、文件,这里就不多做介绍了)

调用云函数传入参数

在小程序端、Web端以及云函数端,我们可以通过callFunction的接口(小程序端为wx.callFunction、云函数端为cloud.callFunction、web端为app.callFunction)来调用云函数,并传入参数:

wx.cloud.callFunction({ name: 'webtest', //被调用的云函数的名称 data: { userInfo:{ name:"李东bbsky" }, id:"20200420001" } })

那我们应该如何获取使用调用云函数时传递的参数呢?我们可以从event对象里拷贝:

const {userInfo,id} = event

访问云接入链接时传入参数

我们通过访问云接入链接或axios等进行HTTP 请求的方式也能向云函数里传递参数,这个参数会在queryStringParameters对象里,我们可以通过

const {name,title} = event.queryStringParameters

云函数配置信息传入参数

我们可以在云开发控制台对云函数进行一些参数的配置,也就是新增环境变量的字段,这个参数在云函数的获取方式如下:

const {school,name} = process.env

14.5.2 后台函数与云接入

有了云接入的概念,我们可以把云函数分为两类,在前面的章节云函数主要用于调用云函数、处理数据库、云存储云调用,我们可以称之为后台函数,而HTTP函数则是我们可以通过标准HTTP请求来调用的。

参考上节Web端云开发的内容,在functions文件夹里新建一个云函数比如backfunction,然后在index.js里输入以下代码,注意有一个dbName的参数会由HTTP请求传入:

const tcb = require('tcb-admin-node') tcb.init({ env: "xly-xrlur" }) const db = tcb.database() const _ = db.command exports.main = (event,context) =>{ const {dbName} = event.queryStringParameters //注意queryStringParameters的来源 return db.collection(dbName) .where({ gdp: _.gt(3000) }) .get() }

然后安装该云函数的依赖,将云函数的代码部署上传到云端,并开启云接入以及设置路由,具体操作前面都有介绍,然后我们在浏览器里打开如下链接,就能看到云函数返回的数据了。

http://xly-xrlur.service.tcloudbase.com/backfunction?dbName=china

在小程序端我们知道获取获取可以使用wx.request()接口,而在web端我们则可以使用axios,在静态托管的html页面,比如打开之前public文件夹里的index.html,输入以下代码,然后打开链接,然后在浏览器的控制台可以获取到的数据啦:

<script src="https://unpkg.com/axios/dist/axios.min.js"></script> <script> const url ="https://xly-xrlur.service.tcloudbase.com/backfunction?dbName=china" axios.get(url).then(res => { console.log(res) console.log(res.data) }).catch(err => { console.log(err) }) </script>

14.5.3 返回集成响应

云函数可以返回String、Object、Number等类型的数据,还能返回集成响应,云接入会将返回值转化成正常的HTTP响应,我们接下来使用云接入来返回一些静态资源文件。

1、使用集成响应返回HTML

使用VS Code在functions文件夹里新建一个云函数,比如sendhtml,以及assets文件夹,里面存放我们要返回的HTML文件,结构如下:

├── sendhtml //sendhtml云函数目录 │ └── assets │ └── index.html │ └── index.js │ └── config.json │ └── package.json

然后在index.js里输入以下代码,读取云函数目录assets文件夹里index.html,并返回HTML,这个云函数就和以往的云函数有很大的不同啦:

const tcb = require('tcb-admin-node') tcb.init({ env: "xly-xrlur" }) const fs = require('fs') const path = require('path') exports.main = async (event,context) =>{ //path.resolve() 方法将路径或路径片段的序列解析为绝对路径 const html = fs.readFileSync(path.resolve(__dirname, './assets/index.html'), { encoding: 'utf-8' }) return { statusCode: 200, headers: { 'content-type': 'text/html' }, body: html } }

在assets文件夹里index.html可以输入一些html代码,然后将sendhtml云函数部署上传并开启云接入,以及设置路由如/sendhtml之后,用浏览器打开云接入的地址,返回的HTML就被浏览器自动解析了。

2、使用集成响应返回其他类型的文件

除了html文件,还能返回其他类型的文件,在响应中,Content-Type 实体头部用于指示资源的MIME媒体类型,告诉Web端返回的内容类型。媒体类型有很多,比如:

类型 描述 典型示例
text 普通文本类型 text/plain, text/html, text/css, text/javascript
image 图像类型 image/gif, image/png, image/jpeg, image/bmp, image/webp, image/x-icon, image/vnd.microsoft.icon
audio 音频文件 audio/midi, audio/mpeg, audio/webm, audio/ogg, audio/wav
video 视频文件 video/webm, video/ogg
application 二进制数据

application/octet-stream, application/pkcs12, application/vnd.mspowerpoint, application/xhtml+xml, application/xmlapplication/pdf

将 content-type 分别设置为 application/javascript、text/css,即可在 body 中返回 JavaScript 文件和css文件,html、js、css文件是静态网站的核心文件,都是可以返回的,这样就用集成响应返回一个完整的静态网站啦。注意用集成请求返回的静态网站和静态托管之间的区别哦

将content-type 设置为 image/png以及将 isBase64Encoded 设置为 true,就能返回图片的二进制文件,这个也可以和云存储结合起来使用。比如我们可以写如下云函数,先下载云存储里面的图片,将Buffer转成base64格式的图片,然后返回,这样我们就能通过云接入的链接查看到图片了:

const cloud = require('wx-server-sdk') cloud.init({ env: "xly-xrlur" }) exports.main = async (event,context) =>{ const fileID = 'cloud://xly-xrlur.786c-xly-xrlur-1300446086/1572315793634-953.png' const res = await cloud.downloadFile({ fileID: fileID, }) const buffer = res.fileContent const base64img = await buffer.toString('base64') return { isBase64Encoded: true, statusCode: 200, headers: { 'content-type': 'image/png' }, body: base64img } }