我认为我已经严格遵循了迄今为止找到的文档和教程,但我仍然无法让它工作。我只是无法说服 AWS 不要触碰我在正文中发布的二进制数据。
在我的应用程序中,我将原始 API 请求的 Content-Type 和 Accept 标头都设置为 application/x-msgpack,我在二进制支持下将其定义为二进制媒体类型:
我没有在方法请求中设置任何内容:
在集成请求中,我没有启用代理,但已启用请求正文直通:
我已为 API 网关执行启用了 CloudWatch 日志,并且可以看到 AWS 仍在对我的二进制数据进行 base64 编码:
17:30:29 开始执行请求:... 17:30:29 HTTP 方法:POST,资源路径:/... 17:30:29 方法请求路径:{} 17:30:29 方法请求查询字符串:{} 17:30:29 方法请求标头:{ 接受=应用程序/x-msgpack, 内容类型=应用程序/x-msgpack, ... } 17:30:29 转换前的方法请求主体:[二进制数据] 17:30:29 端点请求 URI:https://... 17:30:29 端点请求标头:{ 接受=应用程序/x-msgpack, ... [截断 - 我看不到其余的标题] } 17:30:29 转换后的端点请求主体:[Base-64 编码的二进制数据] 17:30:29 正在发送请求至 https://...
请注意,端点请求标头已在 CloudWatch 日志中被截断(对于这个问题,我自己没有截断它们)。因此,我看不到 Content-Type 标头是什么。
请注意“转换前的方法请求主体”和“转换后的端点请求主体”这两行。为什么它仍然会将二进制数据转换为 base-64?
我目前使用过的资料来源有:
- http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-payload-encodings.html
- https://aws.amazon.com/blogs/compute/binary-support-for-api-integrations-with-amazon-api-gateway/
- http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-payload-encodings-workflow.html
- http://docs.aws.amazon.com/apigateway/api-reference/resource/integration/#contentHandling
更新
我已经通过 AWS CLI 检查了集成设置并得到以下结果:
>AWS API 网关获取集成 --rest-api-id ... \ --资源 ID ... \ --http 方法 POST { “集成响应”:{ "200": { “selectionPattern”:“”, “状态码”:“200” } }, “contentHandling”:“CONVERT_TO_TEXT”, "cacheKeyParameters": [], “uri”:“...”, “http方法”:“POST”, "passthroughBehavior": "当无模板时", “缓存命名空间”:“…”, “类型”:“AWS” }
我注意到了这"contentHandling": "CONVERT_TO_TEXT"
一点,并尝试将其覆盖为两者""
(空值,进而完全删除了该属性)并"CONVERT_TO_BINARY"
执行以下操作:
>AWS API 网关更新集成 --rest-api-id ... \ --资源 ID ... \ --http 方法 POST \ --patch-operations'[{"op":"replace","path":"/contentHandling","value":""}]'
我现在看到端点请求被保存为二进制:
10:32:21 转换后的端点请求正文:[二进制数据]
但是,我收到此错误:
10:32:21 转换之前的端点响应主体:{“Type”:“User”,“message”:“无法将请求主体解析为 json:意外字符((CTRL-CHAR,代码 129))...
我没有在 CloudWatch 日志中看到我的 Lambda 函数的任何活动。我的 Lambda 函数并不是试图将传入数据解析为 JSON 的函数。因此,在 API-Lambda 集成路径的某个地方,数据仍然被解析为 JSON,而不是单独保留为二进制。
答案1
我也尝试过将二进制数据从 APIG 发送到 Lambda。我尝试的所有 APIG 选项都转换为 Base64。我现在相信这是由于 Lambda 提取了 JSON 事件数据。
使用 Python 时,我无法使用 @AtesGoral npmjs 压缩,因此最终采用 APIG 到 S3 的解决方案(<10MB 二进制工作)并通过 S3 事件触发器触发 Lambda 函数。FWIW:Lambda 6MB 限制和 Base64 编码(最大 4.4MB 二进制输入)使得无法使用 APIG -> Lambda 实现 S3 分段上传,除非先写入 S3。