Aws lambda Lambda函数向CloudFront返回了无效的请求或响应

Aws lambda Lambda函数向CloudFront返回了无效的请求或响应,aws-lambda,amazon-cloudfront,amazon-cloudwatch,Aws Lambda,Amazon Cloudfront,Amazon Cloudwatch,我正在尝试按照这里的说明进行操作 我已经成功地将CloudFront放在一个静态S3“hello world”HTML文件前面,我想使用lambda edge设置额外的头文件,但是我得到了一个错误。真正令人沮丧的是,我找不到任何错误日志来调试出错的地方。以下是浏览器显示的内容 ERROR The request could not be satisfied. The Lambda function returned an invalid request or response to Clou

我正在尝试按照这里的说明进行操作

我已经成功地将CloudFront放在一个静态S3“hello world”HTML文件前面,我想使用lambda edge设置额外的头文件,但是我得到了一个错误。真正令人沮丧的是,我找不到任何错误日志来调试出错的地方。以下是浏览器显示的内容

ERROR

The request could not be satisfied.

The Lambda function returned an invalid request or response to CloudFront. 
Generated by cloudfront (CloudFront)
Request ID: 2Cqex7euzH0Iigps58i9tMVxdqAaLznL2ZjwqR1sW1AZHz6x2EwfMA==
下面是我的简单lambda的代码:

exports.handler = (event, context, callback) => {
    console.log(event)
    callback(null, 'Hello from Lambda');
};
触发器类型为
viewerresponse
,并附加到我的CloudFront发行版(如果有必要,使用
缓存行为:
)。lambda有一个与
AWSLambdaBasicExecutionRole
相对应的角色,该角色允许对Cloudwatch进行写访问

一旦启用触发器,对web请求的响应就会从我的“Hello world”HTML更改为上面的错误,因此我知道它正在触发lambda。但在lambda仪表板中,它没有显示任何调用或错误。Cloudwatch中未显示任何日志。CloudFront仪表板显示错误(
5xx
),但lambda没有显示任何错误

然后,如果我通过单击部署的函数,将测试事件配置为“CloudFront Modify Response Header”,并点击test,在lambda控制台中测试我的函数,那么它是成功的。Cloudwatch显示测试的日志和控制台输出!但在实时调用的日志中仍然没有任何内容


我唯一的理论是权限有问题,CloudFront实际上无法调用lambda(解释了为什么lambda仪表板中没有任何内容)。最后一件事是CloudFront日志(在S3中)显示带有502错误的web请求和
LambdaValidationError
,但我不知道这是否有帮助。

您在博客文章中看到的示例在Lambda@Edge仍在预览中(在正式推出之前,对特定客户的访问有限),但这不再正确。在服务推出前不久,数据结构发生了变化

响应头数据结构以前是这样的:

headers['Strict-Transport-Security'] = "max-age=31536000; includeSubdomains; preload";
headers['Content-Security-Policy']   = "default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'";
headers['X-Content-Type-Options']    = "nosniff";
headers['strict-transport-security'] = [{
    key:   'Strict-Transport-Security', 
    value: "max-age=31536000; includeSubdomains; preload"
}];

headers['content-security-policy'] = [{
    key:   'Content-Security-Policy', 
    value: "default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'"
}];

headers['x-content-type-options'] = [{
    key:   'X-Content-Type-Options',
    value: "nosniff"
}];
新结构如下所示:

headers['Strict-Transport-Security'] = "max-age=31536000; includeSubdomains; preload";
headers['Content-Security-Policy']   = "default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'";
headers['X-Content-Type-Options']    = "nosniff";
headers['strict-transport-security'] = [{
    key:   'Strict-Transport-Security', 
    value: "max-age=31536000; includeSubdomains; preload"
}];

headers['content-security-policy'] = [{
    key:   'Content-Security-Policy', 
    value: "default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'"
}];

headers['x-content-type-options'] = [{
    key:   'X-Content-Type-Options',
    value: "nosniff"
}];
外部对象中的键必须是内部对象每个成员中的
key
值的小写等价物。为了更准确地反映HTTP头的处理方式,很可能需要对数据结构进行此更改,因为在HTTP/1.x中,它们不区分大小写,但在Javascript对象中密钥区分大小写

如果代码返回的结构不符合CloudFront的要求Lambda@Edge返回时,您看到的错误确实会被抛出。没有生成日志,因为日志没有地方可去——此错误发生在Lambda之外,位于Lambda和CloudFront之间接口边界的CloudFront一侧,而ch不生成任何用户可访问的日志

请参阅文档以了解。

有一些常见的“陷阱”Lambda@Edge和CloudFront。您需要:

  • 发布Lambda函数的新版本
  • 将CloudFront Lambda关联更新到您的新版本,例如:arn:aws:Lambda:us-east-1:572007530218:function:gofaas WebAuthFunction:45
  • 寻找Lambda@Edge请求者所在区域的日志
据我所知,你看不到从主Lambda func的“副本”到“边缘”的调用指标

这与保存代码更改并从监视选项卡跳转到日志的“正常”Lambda web控制台流程不同


请看一看自动部署a的情况,这需要花费大量的设置时间。

如果我下面的答案不能解决您的问题,请将您的代码压缩为a并编辑成问题。您的答案确实解决了我的问题,@sqlbot。我剩下的担心是,在我更改函数时,我无法运行它们每次都是你!我的例子中的问题是返回一个字符串,但是我怎么能从CF和Lambda生成的错误/日志中知道呢?嗯,你知道……你可以随时由我运行它们,只要你有一个资金充足的paypal帐户。:)不过,说真的,你是对的——你没有办法知道,因为当没有节点错误时,CloudFront拒绝Lambda响应,日志就没有地方可去,当然,将错误返回到浏览器不是一个好的做法。但是在文档和示例之间,没有任何东西是无法解决的。确保你检查了所有的“蓝图”。它们生成的有效响应格式完全符合CloudFront喜欢的格式。在AWS论坛上继续使用@michael sqlbot,根据新规范修复了响应事件结构,为我解决了问题。我仍然无法使其正常工作。有人发现了问题吗?@JoeBruno发现了哪个问题?@sqlbot抱歉,我尝试粘贴的代码太长,然后我无法删除我的注释=)今天早上,我通过使用此github repo的“源响应”事件类型实现了这一点: