有奖捉虫:云通信与企业服务文档专题,速来> HOT
本文档描述了 如何使用云函数处理HTTP请求,即 HTTP请求如何转换为云函数的入参,云函数的返回值如何转换为HTTP响应。
阅读该文档前,请先阅读 快速开始 文档,了解如何创建云函数并通过 HTTP 访问云函数。另外,阅读本文档需要对云函数有一定的了解。

云函数代码

以下为一个简单的云函数代码片段:
exports.main = async (event, context) => {
console.log('event: ', event)
console.log('context: ', context)
return { event, context }
}
这段代码并没有 HTTP服务相关的内容,并不会启动一个监听某端口的 HTTP 服务。那么就出现了一个问题:这个云函数怎么接收 HTTP 请求,怎么返回 HTTP 响应。本篇文档将详细解答这个问题。

云函数的入参

通过 HTTP 调用云函数时,HTTP 请求会被转化为称之为集成请求的特殊的结构体,并通过云函数入参 event 传递给云函数入口函数。
集成请求,就是通过 JSON 格式数据描述 HTTP 响应报文的一段数据。
集成请求结构如下:
{
"path": "HTTP请求路径,如 /hello",
"httpMethod": "HTTP请求方法,如 GET",
"headers": {}, // HTTP请求头,key:value,value 为字符串
"multiValueHeaders": {} // HTTP请求头,key:value,value 为字符串数组,用于支持存在相同请求头的情形
"queryStringParameters": {}, // HTTP请求的Query,键值对形式
"requestContext": {}, // 云开发相关信息
"body": "HTTP请求体", // 普通文本 或 Base64 编码,如果是 isBase64Encoded=true,则是 Base64 编码
"isBase64Encoded": false // true or false,表示 body 是否为 Base64 编码,如果是 Base64 编码,业务需要解码后获得元数据。如果 HTTP 请求包体是 二进制数据,则包体内容会被处理成 Base64编码的字符串,此时该值为 true。
}
下面是该结构的一个示例:
{
"path": "/",
"httpMethod": "GET",
"headers": {
"host": "env-id.service.tcloudbase.com",
"connection": "close",
"user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36"
},
"multiValueHeaders": {
"host": ["env-id.service.tcloudbase.com"],
"connection": ["close"],
"user-agent": ["Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"]
},
"queryStringParameters": {},
"isBase64Encoded": false,
"body": ""
}

云函数的返回值

云函数可以返回 numberstringobject 等类型的数据,或者返回 集成响应,随后返回值会被转化为正常的 HTTP 响应。
集成响应,就是通过 JSON 格式数据描述 HTTP 响应报文的一段内容。

返回字符串或数字

云函数返回字符串数字,字符串将会被放在 HTTP 响应 Body 中返回,同时 HTTP 响应的 content-type 会被设置为 text/plain
module.exports.main = async function () {
return "hello gateway"
}
最终 HTTP 响应为:
HTTP/1.1 200 OK
date: Mon, 16 Dec 2019 08:35:31 GMT
content-type: text/plain; charset=utf-8
content-length: 13

hello gateway

返回 Object

云函数返回的 JS 对象会被转换为 JSON 字符串并在 HTTP 响应 Body 中返回,同时 HTTP 响应的 content-type 会被设置为 application/json
module.exports.main = async function () {
return {
foo: "bar"
}
}
最终 HTTP 响应为:
HTTP/1.1 200 OK
date: Mon, 16 Dec 2019 08:35:31 GMT
content-type: application/json; charset=utf-8
content-length: 13

{"foo":"bar"}

返回集成响应

云函数可以返回如下这样特殊结构的集成响应,来自由地控制响应体。
{
"statusCode": 200, // HTTP状态码
"headers": { "headerName": "headerValue", ... }, // HTTP 响应头
"body": "...", // HTTP 响应体,如果需返回 二进制数据,可以将二进制数据编码成 Base64字符串,并将 isBase64Encoded 设置为 true
"isBase64Encoded": false, // HTTP 响应体是否是 Base64 编码
}

使用集成响应返回 HTML

content-type 设置为 text/html,即可在 body 中返回 HTML,会被浏览器自动解析:
module.exports.main = async function () {
return {
statusCode: 200,
headers: {
"content-type": "text/html"
},
body: "<h1>Hello</h1>"
}
}
最终 HTTP 响应为:
HTTP/1.1 200 OK
date: Mon, 16 Dec 2019 08:35:31 GMT
content-type: text/html; charset=utf-8
content-length: 14

<h1>Hello</h1>

使用集成响应返回 JS 文件

content-type 设置为 application/javascript,即可在 body 中返回 JavaScript 文件:
module.exports.main = async function () {
return {
statusCode: 200,
headers: {
"content-type": "application/javascript"
},
body: 'console.log("Hello!")'
}
}
最终 HTTP 响应为:
HTTP/1.1 200 OK
date: Mon, 16 Dec 2019 08:35:31 GMT
content-type: application/javascript; charset=utf-8
content-length: 21

console.log("Hello!")

使用集成响应返回二进制文件

如果返回体是诸如图片、音视频这样的二进制文件,那么可以将 isBase64Encoded 设置为 true,并且将二进制文件内容转为 Base64 编码的字符串,例如:
module.exports.main = async function () {
return {
isBase64Encoded: true,
statusCode: 200,
headers: {
"content-type": "image/png"
},
body: "iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAY..."
}
}
最终 HTTP 响应为一张 PNG 图片:
HTTP/1.1 200 OK
date: Mon, 16 Dec 2019 08:35:31 GMT
content-type: image/png
content-length: 9897

<binary payload...>