AWS Lambda@Edge Viewer 请求失败并显示“正文不是字符串、不是对象或超出最大大小”

Raf*_*aff 5 aws-lambda angular

我正在尝试创建一个 Lambda@Edge 函数来为我的 Angular SPA 应用程序返回开放图 HTML。我已将其安装到 CloudFrond“查看者请求”生命周期中。此 lambda 检查用户代理,如果它是 Facebook 或 Twitter 爬虫,它会返回 HTML(当前在 lambda 中进行硬编码以进行测试)。如果请求来自任何其他用户代理,则该请求将传递到源。传递逻辑工作正常,但如果我尝试拦截并返回爬虫程序的开放图谱 HTML,则会收到错误。

在CloudWatch中,CloudFront报告的错误是:

错误 验证错误:Lambda 函数返回无效正文,正文应为对象类型。

在 Postman 中(通过伪造用户代理),我得到 502:

Lambda 函数结果验证失败:正文不是字符串、不是对象或超出最大大小。

我正在用这个把我的头发拔出来。有任何想法吗?这是我的 lambda。

'use strict';
 
function buildReleaseResponse( request ) {
     
    const content = `<\!DOCTYPE html>
        <html lang="en">
            <head>
                <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
                <meta name="viewport" content="width=device-width, initial-scale=1" />
               
                <meta property="og:type" content="website" />
                <meta property="og:title" content="Hello, World" />
                <meta property="og:description" content="This is an Open Graph test" />
                <meta property="og:image" content="https://cdn.website.com/photos/SGmzAlNmwOGpnMeijMoW9.jpg" />
                <meta property="og:url" content="https://www.website.com/hello-world" />
               
                <title>Hello, World</title>
            </head>
            <body>
                <h1>Open Graph Test</h1>
            </body>
        </html>`;
   
    return {
        statusCode: 200,
        statusDescription: 'OK',
        headers: {
            "content-type": [
                {
                    "key": "Content-Type",
                    "value": "text/html; charset=utf-8"
                }
            ]
        },
        body: content.toString()
    };
   
}
 

exports.handler = ( event, context, callback ) => {
    const { request, response } = event.Records[0].cf;
                                           
    let userAgentStr = "";
       
    if (request.headers['user-agent']) {
      if (request.headers['user-agent'].length > 0) {
          userAgentStr = request.headers['user-agent'][0].value;
      }
    }
   
    let newResponse = null;
   
    if ( userAgentStr.match(/facebookexternalhit|twitterbot/i) ) {
        if ( request.uri.startsWith("/radio/release/") ) {
            newResponse = buildReleaseResponse(request);
        }
    }
   
    if ( newResponse === null ) {
        console.log("Passthrough.");
        callback(null, request);
    }
    else {
        console.log("Overriding response with: " + JSON.stringify(newResponse));
        callback(null, newResponse);
    }   
};
Run Code Online (Sandbox Code Playgroud)

这是 cloudwatch (conole.log) 中显示的响应

{
    "statusCode": 200,
    "statusDescription": "OK",
    "headers": {
        "content-type": [{
            "key": "Content-Type",
            "value": "text/html; charset=utf-8"
        }],
        "cache-control": [{
            "key": "Cache-Control",
            "value": "max-age=100"
        }]
    },
    "body": "<!DOCTYPE html>\n            <html lang=\"en\">\n                <head>\n                    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>\n                    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n                    \n                    <meta property=\"og:type\" content=\"website\" />\n                    <meta property=\"og:title\" content=\"Yo Dog\" />\n                    <meta property=\"og:description\" content=\"Song by Raf Fiol and Mike Patterson\" />\n                    <meta property=\"og:image\" content=\"https://cdn.kompoz.com/photos/SGmzAlNmwOGpnMeijMoW9.jpeg\" />\n                    <meta property=\"og:url\" content=\"https://3-www.kompoz.com/radio/release/yo_dog\" />\n                    \n                    <title>Kompoz.com</title>\n                </head>\n                <body>\n                    <h1>Yo Dog</h1>\n                </body>\n            </html>"
}
Run Code Online (Sandbox Code Playgroud)

这是 CloudFront Lambda 配置

CloudFront Lambda 配置

Raf*_*aff 27

解决了!我很尴尬地报告说,这个问题是由我的打字错误引起的。在我的响应对象中,我有:

"statusCode": 200,
Run Code Online (Sandbox Code Playgroud)

但它本来应该是:

"status": 200,
Run Code Online (Sandbox Code Playgroud)

很高兴地报告它现在正在工作。话虽如此,我希望 AWS 错误消息能够更好一些。消息“主体不是字符串,不是对象,或超过最大大小”真的让我很失望。

  • 这很有趣,因为我也使用了打字稿,但我的类型是为 statusCode: number 定义的,哈哈 (2认同)