Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/amazon-web-services/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js AWS lambda api网关错误“;格式错误的Lambda代理响应“;_Node.js_Amazon Web Services_Aws Lambda_Aws Api Gateway - Fatal编程技术网

Node.js AWS lambda api网关错误“;格式错误的Lambda代理响应“;

Node.js AWS lambda api网关错误“;格式错误的Lambda代理响应“;,node.js,amazon-web-services,aws-lambda,aws-api-gateway,Node.js,Amazon Web Services,Aws Lambda,Aws Api Gateway,我试图用AWS lambda建立一个hello world示例,并通过api网关为其提供服务。我点击了“创建一个lambda函数”,它设置了API GATWAY并选择了空白函数选项。我添加了在上找到的lambda函数: 问题是,当我向它发出GET请求时,它返回502响应{“message”:“internalserver error”}。日志显示“由于配置错误导致执行失败:Lambda代理响应格式错误”。通常,当您看到Lambda代理响应格式错误时,表示Lambda函数的响应与API网关期望的格

我试图用AWS lambda建立一个hello world示例,并通过api网关为其提供服务。我点击了“创建一个lambda函数”,它设置了API GATWAY并选择了空白函数选项。我添加了在上找到的lambda函数:


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

通常,当您看到
Lambda代理响应格式错误时,表示Lambda函数的响应与API网关期望的格式不匹配,如下所示

{
    "isBase64Encoded": true|false,
    "statusCode": httpStatusCode,
    "headers": { "headerName": "headerValue", ... },
    "body": "..."
}
如果未使用Lambda代理集成,则可以登录到API网关控制台并取消选中Lambda代理集成复选框


此外,如果您看到间歇性的
格式错误的Lambda代理响应
,则可能意味着Lambda已阻止对Lambda函数的请求,您需要请求增加Lambda函数的并发执行限制。

是的,因此我认为这是因为您实际上没有返回正确的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.
然后你只需做:

var responder = require('responder')

// some code

callback(null, responder.success({ message: 'hello world'}))

如果lambda用作代理,则响应格式应为

{
"isBase64Encoded": true|false,
"statusCode": httpStatusCode,
"headers": { "headerName": "headerValue", ... },
"body": "..."
}
注:阀体应从顶部开始串接

在Node.js中的Lambda函数中,要返回成功响应,请调用 回调(null,{“statusCode”:200,“body”:“results”})。扔 异常,调用回调(新错误(“内部服务器错误”)。暂时 客户端错误,例如,缺少必需的参数,您可以调用 回调(null,{“statusCode”:400,“body”:“缺少的参数” …“})返回错误而不引发异常


出现此错误是因为我意外地从CloudFormation AWS::Serverless::Api资源中删除了变量ServerlessExpressLambdaFunctionName。此处的上下文是“在AWS Lambda和Amazon API网关之上,使用现有的Node.js应用程序框架运行无服务器应用程序和REST API”

这是一种非常特殊的情况,如果直接传递头,则可能会有此头:

“设置cookie”:[“….”]

但亚马逊需要:


“设置cookie”:“[\\”….\\“]”

如果上述方法对任何人都不起作用,尽管正确设置了响应变量,我还是遇到了此错误

我正在函数中调用RDS数据库。结果表明,导致问题的是该数据库上的安全组规则(入站)

您可能想限制可以访问API的IP地址,但是如果您想让它快速工作/脏掉以测试该更改是否修复了它,您可以将其设置为“接受所有”,就像这样(您也可以将端口上的范围设置为“接受所有端口”,但在本例中我没有这样做):


适用于在响应有效时遇到困难的任何其他人。这不起作用:

callback(null,JSON.stringify( {
  isBase64Encoded: false,
  statusCode: 200,
  headers: { 'headerName': 'headerValue' },
  body: 'hello world'
})
但这确实:

callback(null,JSON.stringify( {
  'isBase64Encoded': false,
  'statusCode': 200,
  'headers': { 'headerName': 'headerValue' },
  'body': 'hello world'
})
此外,响应对象上似乎不允许存在额外的键。

如果使用Go with,则必须使用
事件。APIGatewayProxyResponse

func hello(ctx context.Context, event ImageEditorEvent) (events.APIGatewayProxyResponse, error) {
    return events.APIGatewayProxyResponse{
        IsBase64Encoded: false,
        StatusCode:      200,
        Headers:         headers,
        Body:            body,
    }, nil
}

我已经尝试了上面的所有建议,但当
body
值不是
String

return {
    statusCode: 200,
    headers: {
        "Content-Type": "application/json",
        "Access-Control-Allow-Origin": "*"
    },
    body: JSON.stringify({
        success: true
    }),
    isBase64Encoded: false
};
对于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
    }
注意,
正文
不需要设置,它可以是空的:

        'body': ''
“格式错误的Lambda代理响应”错误的常见原因是
不是
{String:String,…}
键/值对

由于
set cookie
头可以而且确实以倍数出现,因此它们是以倍数表示的 在http.request.callback.response中,作为具有
字符串
值,而不是单个
字符串
。虽然这对开发人员有效,但是AWS API网关不理解它并抛出“格式错误的Lambda代理响应” 错误

我的解决方案是这样做:

function createHeaders(headers) {
  const singleValueHeaders = {}
  const multiValueHeaders = {}
  Object.entries(headers).forEach(([key, value]) => {
    const targetHeaders = Array.isArray(value) ? multiValueHeaders : singleValueHeaders
    Object.assign(targetHeaders, { [key]: value })
  })

  return {
    headers: singleValueHeaders,
    multiValueHeaders,
  }
}

var output = {
  ...{
    "statusCode": response.statusCode,
    "body": responseString
  },
  ...createHeaders(response.headers)
}

请注意,上面的
并不意味着Yada-Yada-Yada。它是.

只是.net核心C#的一段代码:

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;
api网关的响应将是:

{"msg":"Welcome to Belarus! :)"}

这是另一种方法。在API网关集成请求和响应中配置映射模板。转到IntegrationRequest->MappingTemplate->选择“当没有定义模板时”->为内容类型键入application/json。然后,您不必显式地发送json。甚至您在客户端得到的响应也可以是一个简单的字符串

函数响应的格式是此错误的来源。对于要处理Lambda函数响应的API网关,响应必须是以下格式的JSON:

{ “isBase64Encoded”:真|假, “状态代码”:httpStatusCode, “headers”:{“headerName”:“headerValue”,…}, “正文”:“…” }

下面是Node.js中的一个示例函数,其响应格式正确:

exports.handler=(事件、上下文、回调)=>{

})

参考:Python3.7

以前

{
    "isBase64Encoded": False,
    "statusCode": response.status_code,
    "headers": {
                  "Content-Type": "application/json",
               },
     "body": response.json()
}
之后


如果您刚刚接触AWS,只想让URL正常工作

如果尚未为Lambda函数创建触发器,请在Lambda函数应用程序中导航到该函数并创建触发器选择API网关

导航到API网关应用程序->选择您的特定Lambda的API网关(方法执行)->单击集成请求->取消选中“使用Lambda代理集成”(复选框)


然后单击“我有这个问题,它源于一个无效的处理程序代码,看起来非常好:

exports.handler = (event, context) => {
  return {
    isBase64Encoded: false,
    body: JSON.stringify({ foo: "bar" }),
    headers: {
      'Access-Control-Allow-Origin': '*',
    },
    statusCode: 200,
  };
}
我通过检查有些混乱的API网关响应日志得到了提示:

> Endpoint response body before transformations: null
解决这个问题的方法是w
{
    "isBase64Encoded": False,
    "statusCode": response.status_code,
    "headers": {
                  "Content-Type": "application/json",
               },
     "body": response.json()
}
{
    "isBase64Encoded": False,
    "statusCode": response.status_code,
    "headers": {
                  "Content-Type": "application/json",
               },
     "body": str(response.json()) //body must be of string type
}
exports.handler = (event, context) => {
  return {
    isBase64Encoded: false,
    body: JSON.stringify({ foo: "bar" }),
    headers: {
      'Access-Control-Allow-Origin': '*',
    },
    statusCode: 200,
  };
}
> Endpoint response body before transformations: null
exports.handler = async (event, context) => {
    return {
        isBase64Encoded: false,
        body: JSON.stringify({ foo: "bar" }),
        headers: {
          'Access-Control-Allow-Origin': '*',
        },
        statusCode: 200,
    };
}
exports.handler = (event, context) => {
    return new Promise((resolve) => resolve({
        isBase64Encoded: false,
        body: JSON.stringify({ foo: "bar" }),
        headers: {
          'Access-Control-Allow-Origin': '*',
        },
        statusCode: 200,
    }));
}
exports.handler = (event, context, callback) => {
    callback({
        isBase64Encoded: false,
        body: JSON.stringify({ foo: "bar" }),
        headers: {
          'Access-Control-Allow-Origin': '*',
        },
        statusCode: 200,
    });
}