【问题标题】:Lambda edge "The Lambda function returned invalid json: The json output is not parsable."Lambda 边缘“Lambda 函数返回无效 json:json 输出不可解析。”
【发布时间】:2021-08-28 12:07:20
【问题描述】:

我正在尝试使用 nodeJS 在本地读取一个 JS 文件(压缩以便它可以适应 lambda 边缘限制)并在响应中返回它,但我从标题中得到错误。这是为什么? aws edge 是否禁止 gzip 正文?

 'use strict';

exports.handler = (event, context, callback) => {
    const request = event.Records[0].cf.request;

    var noCacheHeaders = {
        'cache-control': [{
            key: 'Cache-Control',
            value: 'no-cache'
        }],
        'pragma': [{
            key: 'Pragma',
            value: 'no-cache'
        }],
        'content-type': [{
            key: 'Content-Type',
            value: 'text/html'
        }]
    };
    if (request.uri.startsWith('/js/') === true) {
        console.log("js path");
        const fs = require('fs');
        fs.readFile('js.gz', function(err, data) {
            if (err) {
                console.log(err);
                // prevent caching on errors
                const response = {
                    status: '500',
                    statusDescription: 'OK',
                    headers: noCacheHeaders,
                    body: "",
                };
                callback(null, response);
            } else {
                const response = {
                    status: '200',
                    statusDescription: 'OK',
                    headers: noCacheHeaders,//cachedHeaders,
                    body: data.toString(),
                };
                callback(null, response);
            }
        });
        return;
    }

        callback(null, request);
        return;

};

【问题讨论】:

  • 看起来您是以 text/html 内容类型发送响应,而不是 JSON,不是吗?
  • @xdumaine JSON 是指 responserequest 对象的序列化传递给 callback() 并在 CloudFront 调用此函数时从 Lambda 接收。它总是在幕后使用 JSON API,而 CloudFront 不喜欢该文档的格式。

标签: node.js amazon-web-services aws-lambda


【解决方案1】:

压缩后的内容不是字符数据——它是二进制数据——这意味着它不能直接序列化为 JSON。由于response 对象由callback() 自动序列化为 JSON,因此数据需要进行 base64 编码(因为任何任意二进制数据的 base64 总是会产生干净的字符数据),然后需要告诉 CloudFront 你什么已经完成,所以它可以将其解码回二进制并交给浏览器。

原则上,你需要更多这样的东西:

      const response = {
        status: '200',
        statusDescription: 'OK',
        headers: noCacheHeaders, //cachedHeaders,
        body: data.toString('base64'), // assuming data is a buffer here (?), encode it
        bodyEncoding: 'base64',        // tell CloudFront it's base64; CloudFront will decode back to binary
      };

https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-generating-http-responses.html#lambda-generating-http-responses-object

【讨论】:

  • 对于压缩的(在云端)webp 图像,'content-type' 应该是 'image/webp' 吗?当我在 cloudfront 中启用 gzip 然后它与The Lambda function returned an invalid json output, parsed json should be an object type. 中断时,我已经有了你在这里写的内容,除了将其更改为非缓存.. 也没有“statusDescription”,但看不出它有什么意义..跨度>
  • 看来你不应该 gzip 图片 => webmasters.stackexchange.com/a/57590
  • 绝妙的答案!如果有人尝试在由源响应事件触发的 CloudFront 中的 Lambda@Edge 函数中返回 gzip 压缩的数据,那么这就是要走的路。太棒了!
  • 您能想到为什么尽管使用了您的解决方案,这个问题仍然会发生吗?我正在为未压缩的 gif 体验这个。我的代码与您发布的完全一样,但我得到了那个错误。
猜你喜欢
  • 1970-01-01
  • 2022-06-22
  • 1970-01-01
  • 1970-01-01
  • 2015-12-09
  • 1970-01-01
  • 2021-06-21
  • 2021-06-28
  • 1970-01-01
相关资源
最近更新 更多