Serverless 触发器 POST 情况差异
阿里云 API 网关
阿里云 API 网关支持不同类型的的 POST 请求。
入参透传的 POST
网关配置如下。
网关透传的 event 特征为有 body
字段以及 isBase64Encoded
为 true,解码比较容易,直接解 base64 即可。
info
透传了之后,即为所有的结果交给函数处理。
示例一 (text/html)
下面的 event,是一个最简单的透传示例,因为其中的 content-type
为 text/html
,所以 body 传递过来 base64 解码的结果也同样是字符串。
{
"body": "eyJjIjoiYiJ9",
"headers": {
"x-ca-dashboard-action": "DEBUG",
"x-ca-dashboard-uid": "125087",
"x-ca-stage": "RELEASE",
"x-ca-dashboard-role": "USER",
"user-agent": "Apache-HttpClient/4.5.6 (Java/1.8.0_172)",
"accept-encoding": "gzip,deflate",
"content-md5": "Kry+hjKjc2lvIrwoJqdY9Q==",
"content-type": "text/html; charset=utf-8"
},
"httpMethod": "POST",
"isBase64Encoded": true,
"path": "/api/321",
"pathParameters": {
"userId": "321"
},
"queryParameters": {}
}
函数结果。
ctx.request.body; // '{"c":"b"}' => string
示例二(application/json)
使用 content-type
为 application/json
,这样框架认为是一个 JSON,会自动被 JSON.parse。
{
"body": "eyJjIjoiYiJ9",
"headers": {
"X-Ca-Dashboard-Action": "DEBUG",
"X-Ca-Dashboard-Uid": "125087",
"X-Ca-Stage": "RELEASE",
"X-Ca-Dashboard-Role": "USER",
"User-Agent": "Apache-HttpClient/4.5.6 (Java/1.8.0_172)",
"Accept-Encoding": "gzip,deflate",
"Content-MD5": "Kry+hjKjc2lvIrwoJqdY9Q==",
"Content-Type": "application/json; charset=utf-8"
},
"httpMethod": "POST",
"isBase64Encoded": true,
"path": "/api/321",
"pathParameters": {
"userId": "321"
},
"queryParameters": {}
}
函数结果。
ctx.request.body; // {"c":"b"} => object
示例三 (application/x-www-form-urlencoded)
使用 content-type
为 application/x-www-form-urlencoded
,这个时候网关不会以 base64 格式透传,这也是前端原生表单的默认提交类型。
info
在 API 网关侧测试,保持“入参透传”下,似乎没有效果,于是我换到了 Postman 进行测试。
Postman 模拟请求如下:
函数拿到的 event 值如下。
{
"body": "{\"c\":\"b\"}",
"headers": {
"accept": "*/*",
"cache-control": "no-cache",
"user-agent": "PostmanRuntime/7.24.1",
"postman-token": "feb51b11-9103-463a-92ff-73076d37b683",
"accept-encoding": "gzip, deflate, br",
"content-type": "application/x-www-form-urlencoded"
},
"httpMethod": "POST",
"isBase64Encoded": false,
"path": "/api/321",
"pathParameters": {
"userId": "321"
},
"queryParameters": {}
}
函数结果。
ctx.request.body; // {"c":"b"} => object
入参映射的 POST
网关配置选择入参映射之后,body 数据类型有两种选择。
一旦选了映射,整个函数拿到的 Headers 中就 没有了 content-type。
这个时候,网关的返回 event 为
{
"body": "eyJjIjoiYiJ9",
"headers": {
"X-Ca-Dashboard-Action": "DEBUG",
"X-Ca-Dashboard-Uid": "111111",
"X-Ca-Dashboard-Role": "USER"
},
"httpMethod": "POST",
"isBase64Encoded": true,
"path": "/api/321",
"pathParameters": {
"userId": "321"
},
"queryParameters": {}
}
函数由于默认没有拿到 header 头,只会对 base64 的结果做处理,结果为字符串。
ctx.request.body; // '{"c":"b"}' => string
阿里云 HTTP 触发器
函数提供的 HTTP 触发器(和网关不同)。
普通 POST(application/json)
验证代码如下。
const body = this.ctx.request.body;
return {
type: typeof body,
body,
};
字符串格式。
ctx.request.body; // "bbb" => string
JSON 格式
ctx.request.body; // {"b":"c"} => object
表单(application/x-www-form-urlencoded)
ctx.request.body; // {"b":"c"} => object
文件上传(Binary)
暂未支持
腾讯云网关
腾讯云提供单独网关。
普通 POST(application/json)
验证代码如下。
const body = this.ctx.request.body;
return {
type: typeof body,
body,
};
使用 Postman 请求。
字符串格式,正常解析。
ctx.request.body; // "bbb" => string
JSON 格式,能正常解析。
ctx.request.body; // {"c":"b"} => object
表单(application/x-www-form-urlencoded)
正常解析为 JSON。
ctx.request.body; // {"c":"b"} => object