AWS lambda api网关错误"格式错误的Lambda代理响应"

jjb*_*kir 59 amazon-web-services node.js aws-lambda aws-api-gateway

我正在尝试使用AWS lambda建立一个hello world示例并通过api网关提供它.我点击了"创建一个Lambda函数",它设置了api gatway并选择了Blank Function选项.我添加了AWS网关入门指南中的lambda函数:

exports.handler = function(event, context, callback) {
  callback(null, {"Hello":"World"});  // SUCCESS with message
};
Run Code Online (Sandbox Code Playgroud)

问题是,当我向它发出GET请求时,它返回502响应{ "message": "Internal server error" }.并且日志显示"由于配置错误导致执行失败:格式错误的Lambda代理响应".

Ka *_*ong 78

通常,当您看到时Malformed Lambda proxy response,这意味着您的Lambda函数的响应与API Gateway期望的格式不匹配,就像这样

{
    "isBase64Encoded": true|false,
    "statusCode": httpStatusCode,
    "headers": { "headerName": "headerValue", ... },
    "body": "..."
}
Run Code Online (Sandbox Code Playgroud)

如果您未使用Lambda代理集成,则可以登录API Gateway控制台并取消选中Lambda代理集成复选框.

此外,如果您看到间歇性 Malformed Lambda proxy response,则可能意味着对Lambda函数的请求已被Lambda限制,并且您需要请求Lambda函数的并发执行限制增加.

  • 非常重要的注意事项:“body”值必须字符串化!(通过`json.dumps()`) (5认同)
  • 这是有关它的AWS支持文章:https://aws.amazon.com/premiumsupport/knowledge-center/malformed-502-api-gateway/ (3认同)
  • http://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-output-format (2认同)

sel*_*t91 40

如果lambda用作代理,那么响应格式应该是

{
"isBase64Encoded": true|false,
"statusCode": httpStatusCode,
"headers": { "headerName": "headerValue", ... },
"body": "..."
}
Run Code Online (Sandbox Code Playgroud)

注意:正文应该是字符串化的

  • @Neo您不需要对响应对象进行字符串化.您需要将响应对象的主体键内的数据进行字符串化 (2认同)
  • 其中,从API网关成功调用仅需要`statusCode`。 (2认同)
  • 确保身体被绳化对我来说很有效。非常感谢+1 (2认同)
  • “身体应该被串起来”天哪,谢谢你 (2认同)

Mrk*_*dig 25

是的所以我认为这是因为你实际上没有在那里返回正确的http响应,这就是你得到错误的原因.

我个人使用一组这样的函数:

    module.exports = {
        success: (result) => {
            return {
                statusCode: 200,
                headers: {
                    "Access-Control-Allow-Origin" : "*", // Required for CORS support to work
                    "Access-Control-Allow-Credentials" : true // Required for cookies, authorization headers with HTTPS
                },
                body: JSON.stringify(result),
            }
        },
        internalServerError: (msg) => {
            return {
                statusCode: 500,
                headers: {
                    "Access-Control-Allow-Origin" : "*", // Required for CORS support to work
                    "Access-Control-Allow-Credentials" : true // Required for cookies, authorization headers with HTTPS
                },
                body: JSON.stringify({
                    statusCode: 500,
                    error: 'Internal Server Error',
                    internalError: JSON.stringify(msg),
                }),
            }
        }
} // add more responses here.
Run Code Online (Sandbox Code Playgroud)

然后你只需:

var responder = require('responder')

// some code

callback(null, responder.success({ message: 'hello world'}))
Run Code Online (Sandbox Code Playgroud)


max*_*paj 20

您的 Node.js 处理程序需要返回 Promise 或使用回调函数。

我遇到了这个问题,它源于一个看起来完全正常的无效处理程序代码:

exports.handler = (event, context) => {
    return {
       isBase64Encoded: false,
       body: JSON.stringify({ foo: "bar" }),
       headers: {
          'Access-Control-Allow-Origin': '*',
       },
       statusCode: 200,
    };
}
Run Code Online (Sandbox Code Playgroud)

该处理程序之前是在async没有使用过的情况下声明的await,因此我删除了该async关键字,但没有意识到 Lambda 期望您的处理程序函数返回 Promise(异步/等待)或调用回调。

我通过检查有些令人困惑的 API Gateway 响应日志得到了提示:

> Endpoint response body before transformations: null
Run Code Online (Sandbox Code Playgroud)

修复它的方法是

  • 返回一个承诺:
exports.handler = (event, context) => {
    return new Promise((resolve) => resolve({
        isBase64Encoded: false,
        body: JSON.stringify({ foo: "bar" }),
        headers: {
            'Access-Control-Allow-Origin': '*',
        },
        statusCode: 200,
    }));
}
Run Code Online (Sandbox Code Playgroud)
  • 使用回调:
exports.handler = (event, context, callback) => {
    callback({
        isBase64Encoded: false,
        body: JSON.stringify({ foo: "bar" }),
        headers: {
            'Access-Control-Allow-Origin': '*',
        },
        statusCode: 200,
    });
}
Run Code Online (Sandbox Code Playgroud)
  • 添加async关键字(异步函数隐式返回 Promise),我不推荐这种方法,因为其他一些开发人员或 IDE 重构工具会出现并删除据称不必要的内容async
exports.handler = async (event, context) => {
    return {
        isBase64Encoded: false,
        body: JSON.stringify({ foo: "bar" }),
        headers: {
            'Access-Control-Allow-Origin': '*',
        },
        statusCode: 200,
    };
}
Run Code Online (Sandbox Code Playgroud)

  • 我做了完全相同的事情 - 删除了“async”,因为我删除了“await”并开始遇到完全相同的问题!你的帖子真的很有帮助。谢谢! (3认同)

par*_*y72 9

对于 Python3:

import json

def lambda_handler(event, context):
    return {
        'statusCode': 200,
        'headers': {
            'Content-Type': 'application/json',
            'Access-Control-Allow-Origin': '*'
        },
        'body': json.dumps({
            'success': True
        }),
        "isBase64Encoded": False
    }
Run Code Online (Sandbox Code Playgroud)

注意body不需要设置,它可以是空的:

        'body': ''
Run Code Online (Sandbox Code Playgroud)


Nig*_*ist 7

只是一段.net coreC#的代码:

using Amazon.Lambda.APIGatewayEvents;
...
var response = new APIGatewayProxyResponse
{
   StatusCode = (int)HttpStatusCode.OK,
   Body = JsonConvert.SerializeObject(new { msg = "Welcome to Belarus! :)" }),
   Headers = new Dictionary<string, string> { { "Content-Type", "application/json" } }
};
return response;
Run Code Online (Sandbox Code Playgroud)

lambda 的响应将是:

{"statusCode":200,"headers":{"Content-Type":"application/json"},"multiValueHeaders":null,"body":"{\"msg\":\"Welcome to Belarus! :)\"}","isBase64Encoded":false}
Run Code Online (Sandbox Code Playgroud)

API 网关的响应将是:

{"msg":"Welcome to Belarus! :)"}
Run Code Online (Sandbox Code Playgroud)

  • 天啊,非常感谢你,在我花了几个小时试图弄清楚如何在响应中获取标题之后,你刚刚救了我。我尝试了纯 JSON,但没有成功。我尝试了键值对,但没有成功。字典是正确的选择!谢谢你! (2认同)

Jon*_*han 6

来自AWS文档

在Node.js中的Lambda函数中,要返回成功的响应,请调用callback(null,{"statusCode":200,"body":"results"}).要抛出异常,请调用callback(新错误('内部服务器错误')).对于客户端错误,例如,缺少必需参数,您可以调用callback(null,{"statusCode":400,"body":"Missing parameters of ..."})来返回错误而不抛出例外.


Cir*_*yon 5

对于那些在回应看似有效时感到挣扎的人。这不起作用:

callback(null,JSON.stringify( {
  isBase64Encoded: false,
  statusCode: 200,
  headers: { 'headerName': 'headerValue' },
  body: 'hello world'
})
Run Code Online (Sandbox Code Playgroud)

但这确实:

callback(null,JSON.stringify( {
  'isBase64Encoded': false,
  'statusCode': 200,
  'headers': { 'headerName': 'headerValue' },
  'body': 'hello world'
})
Run Code Online (Sandbox Code Playgroud)

此外,响应对象上似乎不允许出现额外的键。


Lon*_*yen 5

我已经尝试了上述所有建议,但它不起作用,而body价值不是String

return {
    statusCode: 200,
    headers: {
        "Content-Type": "application/json",
        "Access-Control-Allow-Origin": "*"
    },
    body: JSON.stringify({
        success: true
    }),
    isBase64Encoded: false
};
Run Code Online (Sandbox Code Playgroud)