阿里云 API 网关

阿里云 API 网关支持不同类型的的 POST 请求。

入参透传的 POST

网关配置如下。
image.png

网关透传的 event 特征为有 body 字段以及 isBase64Encoded 为 true,解码比较容易,直接解 base64 即可。

:::info 透传了之后,即为所有的结果交给函数处理。 :::

示例一 (text/html)

下面的 event,是一个最简单的透传示例,因为其中的 content-typetext/html ,所以 body 传递过来 base64 解码的结果也同样是字符串。

  1. {
  2. "body": "eyJjIjoiYiJ9",
  3. "headers": {
  4. "x-ca-dashboard-action": "DEBUG",
  5. "x-ca-dashboard-uid": "125087",
  6. "x-ca-stage": "RELEASE",
  7. "x-ca-dashboard-role": "USER",
  8. "user-agent": "Apache-HttpClient/4.5.6 (Java/1.8.0_172)",
  9. "accept-encoding": "gzip,deflate",
  10. "content-md5": "Kry+hjKjc2lvIrwoJqdY9Q==",
  11. "content-type": "text/html; charset=utf-8"
  12. },
  13. "httpMethod": "POST",
  14. "isBase64Encoded": true,
  15. "path": "/api/321",
  16. "pathParameters": {
  17. "userId": "321"
  18. },
  19. "queryParameters": {}
  20. }

函数结果。

  1. ctx.request.body // '{"c":"b"}' => string

示例二(application/json)

**
使用 content-typeapplication/json ,这样框架认为是一个 JSON,会自动被 JSON.parse。

  1. {
  2. "body": "eyJjIjoiYiJ9",
  3. "headers": {
  4. "X-Ca-Dashboard-Action": "DEBUG",
  5. "X-Ca-Dashboard-Uid": "125087",
  6. "X-Ca-Stage": "RELEASE",
  7. "X-Ca-Dashboard-Role": "USER",
  8. "User-Agent": "Apache-HttpClient/4.5.6 (Java/1.8.0_172)",
  9. "Accept-Encoding": "gzip,deflate",
  10. "Content-MD5": "Kry+hjKjc2lvIrwoJqdY9Q==",
  11. "Content-Type": "application/json; charset=utf-8"
  12. },
  13. "httpMethod": "POST",
  14. "isBase64Encoded": true,
  15. "path": "/api/321",
  16. "pathParameters": {
  17. "userId": "321"
  18. },
  19. "queryParameters": {}
  20. }

函数结果。

  1. ctx.request.body // {"c":"b"} => object

示例三 (application/x-www-form-urlencoded)

**
使用 content-typeapplication/x-www-form-urlencoded ,这个时候网关不会以 base64 格式透传,这也是前端原生表单的默认提交类型。

:::info 在 API 网关侧测试,保持“入参透传”下,似乎没有效果,于是我换到了 Postman 进行测试。 :::

Postman 模拟请求如下:
image.png
函数拿到的 event 值如下。

  1. {
  2. "body": "{\"c\":\"b\"}",
  3. "headers": {
  4. "accept": "*/*",
  5. "cache-control": "no-cache",
  6. "user-agent": "PostmanRuntime/7.24.1",
  7. "postman-token": "feb51b11-9103-463a-92ff-73076d37b683",
  8. "accept-encoding": "gzip, deflate, br",
  9. "content-type": "application/x-www-form-urlencoded"
  10. },
  11. "httpMethod": "POST",
  12. "isBase64Encoded": false,
  13. "path": "/api/321",
  14. "pathParameters": {
  15. "userId": "321"
  16. },
  17. "queryParameters": {}
  18. }

函数结果。

  1. ctx.request.body // {"c":"b"} => object

入参映射的 POST

网关配置选择入参映射之后,body 数据类型有两种选择。

image.png

一旦选了映射,整个函数拿到的 Headers 中就 没有了 content-type

这个时候,网关的返回 event 为

  1. {
  2. "body": "eyJjIjoiYiJ9",
  3. "headers": {
  4. "X-Ca-Dashboard-Action": "DEBUG",
  5. "X-Ca-Dashboard-Uid": "111111",
  6. "X-Ca-Dashboard-Role": "USER"
  7. },
  8. "httpMethod": "POST",
  9. "isBase64Encoded": true,
  10. "path": "/api/321",
  11. "pathParameters": {
  12. "userId": "321"
  13. },
  14. "queryParameters": {}
  15. }

函数由于默认没有拿到 header 头,只会对 base64 的结果做处理,结果为字符串。

  1. ctx.request.body // '{"c":"b"}' => string

阿里云 HTTP 触发器

函数提供的 HTTP 触发器(和网关不同)。

普通 POST(application/json)

验证代码如下。

  1. const body = this.ctx.request.body;
  2. return {
  3. type: typeof body,
  4. body
  5. };

字符串格式。

image.png

  1. ctx.request.body // "bbb" => string

JSON 格式

image.png

  1. ctx.request.body // {"b":"c"} => object

表单(application/x-www-form-urlencoded)

image.png

  1. ctx.request.body // {"b":"c"} => object

文件上传(Binary)

暂未支持

腾讯云网关

腾讯云提供单独网关。

普通 POST(application/json)

验证代码如下。

  1. const body = this.ctx.request.body;
  2. return {
  3. type: typeof body,
  4. body
  5. };

使用 Postman 请求。

字符串格式,正常解析。

image.png

  1. ctx.request.body // "bbb" => string

JSON 格式,能正常解析。
image.png

  1. ctx.request.body // {"c":"b"} => object

表单(application/x-www-form-urlencoded)

正常解析为 JSON。

image.png

  1. ctx.request.body // {"c":"b"} => object