如何将来自POST的params从Amazon API Gateway传递到AWS Lambda

eco*_*rvo 42 amazon-web-services aws-lambda aws-api-gateway

在此问题中如何从Amazon API Gateway将查询字符串或路由参数传递给AWS Lambda

演示了如何使用API​​网关将查询字符串参数映射到AWS lambda.我想做同样的事情,但映射POST值而不是查询字符串.我试过了:

{
    "values": "$input.params()"
}
Run Code Online (Sandbox Code Playgroud)

但没有工作,我没有看到实际的表格数据.BTW我发帖使用:

application/x-www-form-urlencoded

我得到了我的lambda函数的响应,所以我知道它正在调用lambda,但我的问题是我没有在任何地方看到POST参数.我可以弄清楚如何映射它们.我把所有我在Lambda一侧转移到这里,它是:

 {"values":"{path={}, querystring={}, header={Accept=*/*, Accept-Encoding=gzip, deflate, Accept-Language=en-US,en;q=0.8, Cache-Control=no-cache, CloudFront-Forwarded-Proto=https, CloudFront-Is-Desktop-Viewer=true, CloudFront-Is-Mobile-Viewer=false, CloudFront-Is-SmartTV-Viewer=false, CloudFront-Is-Tablet-Viewer=false, CloudFront-Viewer-Country=US, Content-Type=application/x-www-form-urlencoded, Origin=chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop, Postman-Token=7ba28698-8753-fcb1-1f48-66750ce12ade, Via=1.1 6ba5553fa41dafcdc0e74d152f3a7a75.cloudfront.net (CloudFront), X-Amz-Cf-Id=sc8C7dLcW0BHYopztNYrnddC0hXyFdBzHv0O9aWU1gKhd1D_J2HF3w==, X-Forwarded-For=50.196.93.57, 54.239.140.62, X-Forwarded-Port=443, X-Forwarded-Proto=https}}"}
Run Code Online (Sandbox Code Playgroud)

Mar*_*row 69

r7kamura的好答案.此外,这是一个可理解且强大的映射模板的示例application/x-www-form-urlencoded,适用于所有情况(假设POST):

{
    "data": {
        #foreach( $token in $input.path('$').split('&') )
            #set( $keyVal = $token.split('=') )
            #set( $keyValSize = $keyVal.size() )
            #if( $keyValSize >= 1 )
                #set( $key = $util.urlDecode($keyVal[0]) )
                #if( $keyValSize >= 2 )
                    #set( $val = $util.urlDecode($keyVal[1]) )
                #else
                    #set( $val = '' )
                #end
                "$key": "$val"#if($foreach.hasNext),#end
            #end
        #end
    }
}
Run Code Online (Sandbox Code Playgroud)

它会改变一个输入

name=Marcus&email=email%40example.com&message=
Run Code Online (Sandbox Code Playgroud)

{
    "data": {
                "name": "Marcus",
                "email": "email@example.com",
                "message": ""
    }
}
Run Code Online (Sandbox Code Playgroud)

Lambda处理程序可以像这样使用它(这个返回所有输入数据):

module.exports.handler = function(event, context, cb) {
  return cb(null, {
    data: event.data
  });
};
Run Code Online (Sandbox Code Playgroud)

  • 男人,甚至不是一个单一的upvote,这对我来说很漂亮,谢谢! (3认同)

r7k*_*ura 20

您可以通过在集成设置中配置映射模板,将任何请求正文数据转换为有效的JSON格式,以便AWS Lambda可以接收它.

目前似乎亚马逊API网关尚未正式支持application/x-www-form-urlencoded,但是avilewin 在AWS论坛上发布了一个解决方案.在映射模板中,您可以使用速度模板语言(VTL),因此您需要做的是配置将application/x-www-form-urlencoded格式转换为有效JSON格式的映射模板.当然这是一个肮脏的解决方案,但我认为这是目前唯一的方法.

  • AWS API Gateway 不支持 `application/x-www-form-urlencoded` 仍然有效吗? (2认同)

Jon*_*han 17

如果启用Lambda代理集成 在此输入图像描述

POST正文将来自:

event['body']['param']
Run Code Online (Sandbox Code Playgroud)

GET参数和标题也可以通过

event['pathParameters']['param1']
event["queryStringParameters"]['queryparam1']
event['requestContext']['identity']['userAgent']
event['requestContext']['identity']['sourceIP']
Run Code Online (Sandbox Code Playgroud)

  • `event.body` 返回 `id="some"`,但无法通过 `event.body.id` 或您编写的方式获取 `id`。 (2认同)

adv*_*ncd 11

您可以使用API​​网关模板将参数转换为JSON:https: //forums.aws.amazon.com/thread.jspa?messageID = 673012&tstart = 0#673012

或者您可以使用QueryString解析器pacakge在lambda函数本身中执行此操作:https://www.npmjs.com/package/qs

var qs = require('qs');
var obj = qs.parse('a=c');  // { a: 'c' } 
Run Code Online (Sandbox Code Playgroud)

如果亚马逊为这样的功能添加内置支持,我将使用它,但在那之前我个人更喜欢第二种方式,因为如果出现问题它更干净,更容易调试.

2017年7月更新:

您可以使用默认支持它的代理集成:http: //docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for-lambda.html


Gia*_*ati 5

我发现了一个非常简单的解决方案,我认为值得分享,因为我花了一些时间才找到这个最小的工作代码。

如果您有一个通用表单,发送内容类型为 application/x-www-form-urlencoded 的数据,只需标记“Lambda 代理集成”,然后您将在 event.body 中找到编码的表单数据,可以使用 Node.js 进行解析查询字符串本机模块。

const querystring = require('querystring')

function handler (event, context, callback) {
  // Read form data.
  const { user, pass } = querystring.parse(event.body)

  // Follows your code to handle request.
}
Run Code Online (Sandbox Code Playgroud)


Mar*_*nko 5

扩展@ markus-whybrow答案:

{
        #foreach( $token in $input.path('$').split('&') )
            #set( $keyVal = $token.split('=') )
            #set( $keyValSize = $keyVal.size() )
            #if( $keyValSize >= 1 )
                #set( $key = $util.urlDecode($keyVal[0]) )
                #if( $keyValSize >= 2 )
                    #set( $val = $util.urlDecode($keyVal[1]) )
                #else
                    #set( $val = '' )
                #end
                "$key": "$util.escapeJavaScript($val)"#if($foreach.hasNext),#end
            #end
        #end
    }
Run Code Online (Sandbox Code Playgroud)

这消除了“数据”,并且还解决了如果您在一个值中使用双引号引起的情况。


Upd*_*ava 5

2021 年 6 月

POST的映射模板application/x-www-form-urlencoded:(Python)

from base64 import b64decode
from urllib.parse import parse_qs

def lambda_handler(event, context):
    params = parse_qs(b64decode(event.get('body')).decode('utf-8'))
    print(params.get('name')[0])
    print(params.get('email')[0])
Run Code Online (Sandbox Code Playgroud)

同样,使用 params 字典和参数名称执行任何您想要执行的操作。