【问题标题】:how can I get raw body string in Lambda (API gateway Lambda proxy)如何在 Lambda 中获取原始正文字符串(API 网关 Lambda 代理)
【发布时间】:2017-06-30 22:34:50
【问题描述】:

在 API 网关上启用 CORS 后,这是我发送到 http 端点的请求:

    $.ajax({
        type: 'put',
        url: 'https://xxxxx.execute-api.us-east-1.amazonaws.com/dev/artist/application/julian_test',
        data: {params: {param1: "543543", param2: "fdasghdfghdf", test: "yes"}},
        success: function(msg){
            console.log(msg);
        },
        error: function(msg){
            console.log(msg);
        }
    });

这里是 lambda 函数(我使用的是 node serverless 包,代码没有错误):

module.exports.julian_test = (event, context, callback) => {
    console.log(event);
    console.log(event.body);

var response_success = {
    statusCode: 200,
    headers: {
        "Access-Control-Allow-Origin": "*"
    },
    body: JSON.stringify({
        firstUser: {
            username: "Julian",
            email: "awesome"
        },
        secondUser: {
            username: "Victor",
            email: "hello world"
        },
        thirdUser: {
            username: "Peter",
            email: "nice"
        }
    })
};
    callback(null, response_success);
};

console.log(event.body) 注销: params%5Bparam1%5D=543543&params%5Bparam2%5D=fdasghdfghdf&params%5Btest%5D=yes

,这不是我想要的格式。我检查了 OPTIONS 集成请求/正文映射模板,这是快照。

我试图删除“应用程序/json”,但之后我收到以下响应:

XMLHttpRequest 无法加载 https://xxxxxx.execute-api.us-east-1.amazonaws.com/dev/artist/application/julian_test。对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,Origin 'null' 不允许访问。响应的 HTTP 状态代码为 500。

有谁知道如何在后端 lambda 中获取原始字符串请求正文?请帮忙!

【问题讨论】:

    标签: amazon-web-services lambda aws-lambda aws-api-gateway


    【解决方案1】:

    截图是用于 CORS 的 OPTIONS 方法。

    您的实际 Lambda 函数调用可能是通过 POST 方法进行的。请查看 POST 方法下的集成请求正文映射模板。如果设置为通过正文(这是默认设置),则输入请求中的正文应按原样传递给 Lambda。

    请使用 API Gateway 控制台中的测试功能来查看输入如何转换为集成请求。那应该可以帮助您进行调试。

    【讨论】:

      【解决方案2】:

      这里有两件事:

      首先,在您的 API Gateway 资源下,转到 Method Response 并确保您有对 200 OK mapped 的响应。

      其次,在您的 API Gateway 资源下,转到Integration Request,在Body Mapping Templates 下选择application/json 并在模板文本编辑器中输入以下代码:

      {
        "method": "$context.httpMethod",
        "body" : $input.json('$'),
        "headers": {
          #foreach($param in $input.params().header.keySet())
          "$param": "$util.escapeJavaScript($input.params().header.get($param))" #if($foreach.hasNext),#end
      
          #end
        },
        "queryParams": {
          #foreach($param in $input.params().querystring.keySet())
          "$param": "$util.escapeJavaScript($input.params().querystring.get($param))" #if($foreach.hasNext),#end
      
          #end
        },
        "pathParams": {
          #foreach($param in $input.params().path.keySet())
          "$param": "$util.escapeJavaScript($input.params().path.get($param))" #if($foreach.hasNext),#end
      
          #end
        }  
      }
      

      应用此功能后,您可以像这样访问您的请求对象:(Node.js)

        console.log('Body:', event.body);
        console.log('Headers:', event.headers);
        console.log('Method:', event.method);
        console.log('Params:', event.params);
        console.log('Query:', event.query);
      

      我花了一段时间才弄清楚这一点,向 Kenn Brodhagen 提供解释: tutorial

      【讨论】:

      • 这实际上不允许您获取请求的原始正文字符串,它正在解析它并将其作为 json 返回。有什么方法可以获取原始字符串,因为我需要做一些签名请求。
      【解决方案3】:

      获得真正的原始 AWS Lambda 请求的唯一方法是通过Stream for Handler Input

      根据文档:

      输入负载必须是有效的 JSON,但输出流不带有这样的限制。支持任何字节。

      Java 中的流式 AWS Lambda 输入和输出示例:

      public void handler(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
              int letter;
              while((letter = inputStream.read()) != -1)
              {
                  outputStream.write(Character.toUpperCase(letter));
              }
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-27
        • 2017-07-26
        • 2017-11-06
        • 2019-11-27
        相关资源
        最近更新 更多