【问题标题】:Gzipping in a AWS Lambda function served through API Gateway V2 throws ERR_CONTENT_DECODING_FAILED on the browser在通过 API Gateway V2 提供的 AWS Lambda 函数中进行 Gzip 压缩会在浏览器上引发 ERR_CONTENT_DECODING_FAILED
【发布时间】:2020-10-23 18:49:06
【问题描述】:

我想通过 AWS Gateway V2 提供压缩后的内容。不幸的是,AWS Gateway V2 没有开箱即用的压缩功能,所以我在通过网络发送之前对 lambda 进行压缩。

问题是,在所有设置之后,请求都以ERR_CONTENT_DECODING_FAILED 失败。当我在本地运行端点时它工作正常,所以我知道该功能在我的开发服务器中工作。我需要做什么才能让 API Gateway V2 了解不要触摸此响应并按原样发送它?

【问题讨论】:

    标签: node.js express aws-lambda gzip aws-api-gateway


    【解决方案1】:

    经过几个小时后,我现在可以通过 AWS Lambda 成功地提供压缩的 React SSR 内容。这是我想出的,我希望将来能节省一些时间。

    API Gateway V2 没有在 AWS 端压缩响应的选项是故意的。 AWS Gateway V2 比 AWS Gateway 便宜,这是因为功能更少。事实上,AWS Gateway V2 比 V1 简单得多,而且不会妨碍您。

    如果您使用 AWS 库将您的服务器“代理”到 lambda 函数,您需要确保以下几点:

    isBase64Encoded 作为 lambda 的属性返回

    isBase64Encoded 指示 AWS 不对您提供的数据应用任何类型的规则,而只是“通过”。因为它是base64 编码的,AWS 可以简单地解码字符串并将原始解码数据提供给客户端。这意味着其他类型的压缩,例如 Brotli,可以毫无问题地使用。请记住,您需要正确设置 Content 标头。

    body 被压缩并以 base64 编码

    这部分尤为重要;您可能通过线路将数据作为二进制数据发送,因此当 AWS 尝试再次解析它时,它会变成垃圾并直接提供给浏览器。

    您可以做的一件事是在本地运行 SAM 中的 lambda 并查看它返回的内容。这就是我能够弄清楚通过线路发送到 AWS 的数据被压缩的方式,但它的数据格式错误(它只是字符串垃圾,当我 console.log'd 时它没有正确编码)。当您通过 SAM 运行它时,响应应该是 base64 编码字符串。

    关于aws-serverless-express 或任何等价物的更多说明

    如果您使用库将 Node 服务器代理到 API Gateway V2,请确保您通读源代码并了解其工作原理。在我的例子中,我需要捕获这个库公开的 promise 返回的结果,然后添加 isBase64Encoded 属性(在这些场景中应该是 true)。

    为了确保能够将 base64 编码内容与常规 UTF-8 内容区分开来,我所做的另一件事是,我在名为 x-base64-content 的响应中添加了一个标头,并将其设置为 true,以便我可以阅读这个头在 lambda 函数中,然后传入isBase64Encoded。如果我决定这样做,这也使我能够从服务器传递正常数据。因为这个头与客户端无关,所以我确保之后删除它。

    我希望这对正在通过 AWS Lambda 和 API Gateway V2 提供压缩内容服务的人有所帮助。

    【讨论】:

    • 非常感谢您的详细回答。我有一个问题:我使用 aws-serverless-express 作为代理创建了一个 API 和一个带有 serverless 的 lambda。我使用的 AWS Api 网关是 V1 对吗?我该如何检查?非常感谢
    • @MajinDageta AWS API Gateway 现在大多是 V2。您可能应该忽略 V1 的任何文档。
    猜你喜欢
    • 2023-03-05
    • 2017-09-17
    • 1970-01-01
    • 2021-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-13
    相关资源
    最近更新 更多