API网关 - 发布multipart\form-data

Hex*_*xie 25 amazon-web-services aws-lambda aws-api-gateway

似乎我的问题可能与类似.

我的API网关中有一个API,我正在通过POST的multipart/form-data文件的端点进行HTTP代理.

如果我直接调用http端点(而不是通过API网关) - 使用邮递员,它按预期工作,但是,使用API​​网关端点(通过邮递员)失败.

我已经比较了两个似乎相同的请求(通过fiddler和CloudWatch日志):

请求直接API调用(工作):

POST https://domainname/api/v1/documents HTTP/1.1
Host: api.service
Connection: keep-alive
Content-Length: 202
Authorization: AuthToken
Postman-Token: a75869d6-1d64-6b9f-513d-a80ac192c8e1
Cache-Control: no-cache
Origin: chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop
docMetaInfo: some extra data needed
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryB85rsPlMffA2fziS
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8

------WebKitFormBoundaryB85rsPlMffA2fziS
Content-Disposition: form-data; name=""; filename="Test.txt"
Content-Type: text/plain

This is a test Text File
------WebKitFormBoundaryB85rsPlMffA2fziS--
Run Code Online (Sandbox Code Playgroud)

来自API网关的请求(不工作):

POST https://GATEWAY_domainname/api/v1/documents HTTP/1.1
Host: api-Gateway.service
Connection: keep-alive
Content-Length: 202
Authorization: AuthToken
Postman-Token: e25536fa-3dfa-ddcb-8ca6-3f3552d2bc40
Cache-Control: no-cache
Origin: chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop
docMetaInfo: some extra data needed
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarybX9MyWBsuLGm6QIC

x-api-key: *********************
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8

------WebKitFormBoundarybX9MyWBsuLGm6QIC
Content-Disposition: form-data; name=""; filename="Test.txt"
Content-Type: text/plain

This is a test Text File
------WebKitFormBoundarybX9MyWBsuLGm6QIC--
Run Code Online (Sandbox Code Playgroud)

我从网关端尝试了一些东西,包括更改Integration Request为同一内容类型映射一个新的主体,没有运气.

据我所知,我应该只需要passthrough这个调用,因此它变得有点混乱 - 应该不需要数据操作/拦截?

我得到的错误是400 - 错误请求(抱怨file未找到),但正如您在请求中看到的那样,它就在那里.

有任何想法吗?

编辑 在同一个APIGateway POST上从CloudWatch登录

在此输入图像描述

错误仍然是400 - 找不到文件

Rya*_*anG 21

API网关当前不支持多部分表单数据.这正在考虑用于未来的发展.在此期间,您需要修改您的客户端以使用多个请求或单个部分请求.

更新:API网关现在支持二进制有效负载.只需将"multipart/form-data"定义为API的二进制媒体类型,并将有效负载直接代理到Lambda函数.从那里你可以解析正文以获取你的文件内容.应该有可用于帮助解析多部分主体的库(例如,NodeJS中的'parse-multipart').

  • @ RyanG-AWS包含`multipart/form-data`作为二进制媒体类型也匹配`multipart/form-data; 边界= 90a8997f`? (5认同)
  • @ RyanG-AWS这没有意义.如果passthrough没有透明地将请求传递到后端......那么它会做什么?(为什么它被称为"passthrough?")这是一个简单的`POST`,带有`Content-Type:multipart/form-data`--称之为"multipart上传"并不是真的听起来像这个或者是. (4认同)
  • 我使用了术语上传,因为多部分表单数据通常包含文件内容作为内容部分之一.为了清晰起见,我编辑了帖子.请记住,API网关不是纯粹的反向代理 - 即使在"直通"模式下,API网关数据平面也会对请求数据执行操作,并且在案例中实现特定的HTTP功能(例如multipart/form-data)以个案为基础.话虽如此,我理解混乱,我认为这是一个限制.我们将考虑优先处理这项工作. (2认同)
  • @Matt,您好,是的-对于此限制,最简单的方法是使用AWS开发工具包和S3签名的URL。请参阅以下链接:http://docs.aws.amazon.com/AmazonS3/latest/dev/ShareObjectPreSignedURLDotNetSDK.html和http://docs.aws.amazon.com/AmazonS3/latest/dev/UploadObjectPreSignedURLDotNetSDK.html (2认同)
  • @ RyanG-AWS“ API网关现在支持二进制有效负载。只需将“ multipart / form-data”定义为二进制媒体类型”。这是在某处记录的吗? (2认同)

Dre*_*Dre 8

对于仍然需要帮助的人,现在已正式记录在案:

https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-payload-encodings-configure-with-console.html

概括来说,步骤如下:

  1. 转到API的“ API网关设置”标签,然后将“ multipart / form-data”添加到“二进制媒体类型”部分。
  2. 将“ Content-Type”和“ Accept”添加到代理方法的请求标头中
  3. 将那些相同的标头添加到集成请求标头中
  4. 重新部署

干杯

  • 这非常有帮助,谢谢!要补充的是,如果您使用 Lambda 代理集成({proxy+}),只需步骤 1 和 4 就足够了。 (2认同)
  • 值得注意的是,一旦添加了二进制媒体类型,lambda“主体”中的内容将进行 Base64 编码。 (2认同)

Swa*_*lih 6

我在与 Tomcat 服务器集成时遇到了同样的问题,我发现需要进行以下更改来修复它。

  1. 通过控制台在 api 网关中的api 的HTTP 请求标头中添加Content-Type或将其添加到开放 api 文档中,例如

    {
        "/yourApi":{
            "post":{
                "operationId":"uploadImageUsingPOST",
                "produces":[
                    "application/json"
                ],
                "parameters":[
                {
                    "name":"Content-Type",
                    "in":"header",
                    "required":false,
                    "type":"string"
                },
                {
                    //Other headers
                }]   
            }
        }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 上述步骤还在您的 api 集成请求的 HTTP 标头中添加 Content-Type,如果没有也添加它,并通过控制台在 api 网关中再添加一个标头Accept =' / '或将其添加到开放 api 文档中,例如

    "requestParameters":{
        "integration.request.header.Accept":"'*/*'",
        "integration.request.header.Content-Type":"method.request.header.Content-Type",
        //Other headers
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 在 api 的集成请求中将内容处理设置为直通。

  4. 通过控制台或打开 api 文档将 multipart/form-data 添加为 api 设置中的二进制媒体类型

    "x-amazon-apigateway-binary-media-types": [
        "multipart/form-data"
    ]
    
    Run Code Online (Sandbox Code Playgroud)
  5. 将以上更改部署到要将图像作为分段上传的所需阶段。

Api 网关会将您的多部分文件作为二进制数组传递,您仍然可以在控制器中使用 @RequestBody MultipartFile multipartFile,spring 会为您解析此二进制文件为多部分。


yas*_*ash 5

已解决https ://github.com/mscdex/busboy/issues/199#issuecomment-505239005

我在 node.js 中使用express-fileupload进行多部分表单数据

然后仅在 AWS API Gateway 上配置设置

选择 API => 设置 => 二进制媒体类型 =>

在此输入图像描述

现在不会损坏 formdata 中的任何文件,一切工作正常。