簡體   English   中英

如何通過代理集成從 AWS API 網關提供二進制數據?

[英]How to serve binary data from AWS API Gateway with proxy integration?

我正在使用 AWS API 網關 (APIG) 和 Lambda 函數構建無服務器 web 站點。 我必須使用代理集成,因為后面的 Lambda function 必須接收 http 請求標頭。 同時,需要提供一些二進制數據。 在我的例子中,favicon.ico 文件。 其他人可能想要提供動態創建的 PDF 或 Excel 文件。 APIG 為此目的提供二進制支持。 使用 base64 對數據進行編碼並配置該 MIME 內容類型,以便在將其提供給客戶端之前對其進行解碼。 但是,這不適用於代理集成。 代理集成只是跳過集成響應部分。

我試圖將 favicon.ico 的請求重定向到 S3 端點,但瀏覽器顯示出奇怪的行為。 因為 ico 文件來自不同的重定向域,而不是相同的域。

使用 base64 對其進行編碼並讓客戶端瀏覽器對其進行解碼不是一種選擇,因為這不是標准的並且可能不適用於所有瀏覽器。

我假設在 AWS 為此添加新功能之前我不能做任何其他事情。 有沒有人研究過這個問題? 有什么想法或建議嗎?

在這里回答我自己的問題。 您應該訪問 AWS 論壇以獲取 AWS 問題。 這里不是很多 AWS 用戶。

答案:代理集成的二進制支持確實有效,它適用於傳入和傳出響應。

有3個因素與此相關:

  1. APIG 二進制支持設置中的 MIME 類型(我在控制台上設置)
  2. 傳入和傳出 JSON 中的“isBase64Encoded”值
  3. 傳出 JSON 中的“內容類型”值

上面的答案意味着是的,您可以接受文件,再次是的,您可以通過代理集成吐出文件。

當用戶“發布”帶有正文並且您設置的 MIME 類型與其匹配時,APIG 會在 base64 中對整個正文部分進行編碼,並用“isBase64Encoded”值表示這一點。 同樣的事情也會發生在傳出的響應上。 如果您想使用二進制數據進行響應,請使用 base64 對其進行編碼,並在傳出的 JSON 中將該值設置為 true。

對於傳入請求,它僅取決於一個因素,即您設置的 MIME 類型。 對於傳出,JSON 中的指示符和 MIME 類型這兩個條件必須匹配。

為簡單起見,我只是將 MIME 類型設置為*/* 每當用戶提交正文中的任何內容時,讓 APIG 編碼然后我解碼。 每當我用二進制響應時,我只需設置指標並以 base64 編碼。 我不會對其他類型(例如 test/html(未壓縮))執行此操作。

如何解決 "application/pdf" header 不起作用和避免使用 */*:請求中的 "Accept" header 必須與網關上的二進制媒體類型完全匹配

  • 如果 Accept 是“*/*”,則網關上的 BinearyMediaType 必須是“*/*”(application/pdf 將不起作用)。
  • 如果 Accept 是“application/pdf”(或 image/png...),則網關上的 BinearyMediaType 必須是“application/pdf”(*/* 將不起作用。)。

我遇到了類似的情況,Node lambda 函數從服務層返回二進制 blob(PDF)。

  1. 配置/作為網關上的二進制媒體類型。 (我嘗試使用 application/pdf,但沒有用?)
  2. 確保來自服務層的響應正文沒有轉換為字符串(我正在使用請求,默認情況下它給我字符串)。 我發送 encoding: null 和請求
  3. 當我從服務層獲取 Buffer 數據時,我使用 Buffer 將響應主體轉換為 base64 編碼。
  4. 在 lambda 輸出中,我將 isBase64Encoded 設置為 true

參考: 這里

在 Lambda 代理集成的情況下,有兩個要求:

  • 二進制文件應該在函數的響應中進行 base64 編碼,包括設置為“true”的“isBase64Encoded”屬性和一個“Content-Type”標頭,以向客戶端指示它返回的數據類型。 請參見 [1] 中的示例。

  • API 設置上的“binaryMediaTypes”必須支持這樣的“Content-Type”,以便有效負載可以作為二進制處理 [2]。

注意:對於代理集成,API Gateway 將整個請求傳遞到您的后端,您無法修改傳遞行為 [3]。

如果您使用“ / ”通配符作為二進制媒體類型,並且來自 Lambda 的響應被標記為非 base64 編碼,則 Lambda 響應將不會被視為二進制,並且響應將以文本格式返回(例如 base64 編碼在如果您對文件進行了編碼)。 請注意,如果您的客戶端不准備處理文本響應,它可能會看到您的二進制文件已損壞。

如果后端集成接收到的負載是 base64 編碼的,API 網關會為注冊為二進制支持的 MIME 類型應用 base64 解碼。

使用映射模板返回二進制文件(一般情況下):

如果您需要在集成響應中選擇“CONVERT_TO_BINARY”,則返回帶有映射模板的二進制文件的問題,這將在應用映射模板之前應用,這將導致失敗。 映射模板僅用於應用程序/json 負載。 將它與其他內容類型和二進制文件一起使用效果不佳,因為映射模板並不適用於那些內容類型和二進制文件。

您提到的映射模板將不起作用。 如果您想要一個二進制文件作為響應,CONVERT_TO_BINARY 將在映射模板之前應用,因此這將不起作用。 這是映射模板的限制,因此建議使用 Lambda 代理集成,或僅從您的 Lambda 模板重新調整 base64 編碼的有效負載,其中沒有 JSON 或其他數據。 使用 $util.base64Decode 也不會產生有效的二進制文件,因為 API Gateway 仍會嘗試將其解釋為 application/json,因此有效負載將被損壞。

以下是您可以考慮的選項:

1- 從您的 lambda 返回應用程序/pdf 作為 base64 編碼的字符串,然后在集成響應傳遞中應用 CONVERT_TO_BINARY。 您還需要在集成響應和方法響應中靜態指定 Content-Type 響應標頭。 將響應映射模板留空,以便傳遞正文並轉換為適當的二進制文件。

2- 使用 Lambda 代理集成並像您一樣返回有效負載,標頭、正文作為 base64 編碼的有效負載和 'isBase64Encoded': true。 API Gateway 將負責設置正確的標頭並將文件作為二進制文件返回。

我看到正確答案遍布多個答案和評論。

  1. 您需要確保不僅遵循有關如何從Lambda 代理返回二進制文件的文檔https://docs.aws.amazon.com/apigateway/latest/developerguide/lambda-proxy-binary-media.html
  2. 您還必須在 API 網關配置二進制媒體類型請不要使用*/* - 這會破壞您的非二進制響應) https://docs.aws.amazon.com/apigateway/latest/developerguide/api -網關有效負載編碼-configure-with-console.html
  3. 最容易被忽視的部分是您的客戶必須提供Accept header 作為他們請求的一部分。 Accept header 的值應該與您用作 Lambda 的返回內容類型的值相匹配。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM