

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 使用 Range 和 partNumber 標頭
<a name="range-get-olap"></a>

**注意**  
自 2025 年 11 月 7 日起，S3 Object Lambda 僅適用於目前正在使用該服務的現有客戶，以及選取 AWS 合作夥伴網路 (APN) 合作夥伴。對於類似於 S3 Object Lambda 的功能，請在此處進一步了解 - [Amazon S3 Object Lambda 可用性變更](https://docs.aws.amazon.com/AmazonS3/latest/userguide/amazons3-ol-change.html)。

在 Amazon S3 Object Lambda 中使用大型物件時，您可以使用 `Range` HTTP 標頭，從物件下載指定的位元組範圍。若要從同一物件內擷取不同的位元組範圍，您可以對 Amazon S3 使用並行連線。您還可以指定 `partNumber` 參數 (1 到 10,000 之間的整數)，其會針對物件的指定部分執行範圍請求。

因為您可能需要多種方法來處理包含 `Range` 或者 `partNumber` 參數的請求，而 S3 Object Lambda 不會將這些參數套用至轉換的物件。相反地，您的 AWS Lambda 函數必須根據您的應用程式需求實作此功能。

若要搭配 S3 Object Lambda 使用 `Range` 和 `partNumber` 參數，請執行下列動作：
+ 在 Object Lambda 存取點組態中啟用這些參數。
+ 撰寫一個 Lambda 函數，其可以處理包含這些參數的請求。

下列步驟說明如何完成這項操作。

## 步驟 1：設定 Object Lambda 存取點
<a name="range-get-olap-step-1"></a>

根據預設，Object Lambda 存取點會以 HTTP 狀態碼 501 (未實作) 錯誤回應任何 `GetObject` 或 `HeadObject` 請求，該請求包含在標頭或查詢參數中的 `Range` 或 `partNumber` 參數。

若要啟用 Object Lambda 存取點以接受此類請求，您必須在 Object Lambda 存取點組態的 `AllowedFeatures` 區段中包括 `GetObject-Range`、`GetObject-PartNumber`、`HeadObject-Range` 或 `HeadObject-PartNumber`。如需更新 Object Lambda 存取點組態的詳細資訊，請參閱 [建立 Object Lambda 存取點](olap-create.md)。

## 步驟 2：在 Lambda 函數中實作 `Range` 或 `partNumber` 處理
<a name="range-get-olap-step-2"></a>

當 Object Lambda 存取點使用範圍 `GetObject` 或 `HeadObject` 請求叫用 Lambda 函數時，`Range` 或 `partNumber` 參數會包含在事件內容中。如下表所述，參數在事件內容中的位置，取決於使用的參數以及將其包含在對 Object Lambda 存取點的原始請求中的方式。


| 參數 | 事件內容位置 | 
| --- | --- | 
| `Range` (標頭) | `userRequest.headers.Range` | 
| `Range` (查詢參數) | `userRequest.url` (查詢參數 `Range`) | 
| `partNumber` | `userRequest.url` (查詢參數 `partNumber`) | 

**重要**  
針對您的 Object Lambda 存取點所提供的預先簽章 URL 不包含來自原始請求的 `Range` 或 `partNumber` 參數。請參閱下列選項，了解如何在 AWS Lambda 函數中處理這些參數。

在擷取 `Range` 或 `partNumber` 值後，您可以根據應用程式的需求採取下列其中一種方法：

1. **將請求的 `Range` 或 `partNumber` 映射到轉換的物件 (建議)。**

   處理 `Range` 或 `partNumber` 請求的最可靠方式是執行以下動作：
   + 從 Amazon S3 擷取完整物件。
   + 轉換物件。
   + 將請求的 `Range` 或 `partNumber` 參數套用至轉換的物件。

   為此，請使用提供的預先簽章 URL 從 Amazon S3 擷取整個物件，然後根據需要處理物件。如需以這種方式處理`Range`參數的範例 Lambda 函數，請參閱 AWS 範例 GitHub 儲存庫中的[此範例](https://github.com/aws-samples/amazon-s3-object-lambda-default-configuration/blob/main/function/nodejs_20_x/src/response/range_mapper.ts)。

1. **將請求的 `Range` 映射到預先簽署的 URL。**

   在某些情況下，Lambda 函數可以將請求的 `Range` 直接映射到預先簽署的 URL，以便從 Amazon S3 中僅擷取部分物件。只有當轉換符合以下兩個條件時，此方法才適用：

   1. 轉換函數可套用於部分物件範圍。

   1. 在轉換函數之前或之後套用 `Range` 參數，將會產生相同的轉換物件。

   例如，將 ASCII 編碼物件中的所有字元轉換為大寫的轉換函數滿足上述兩個條件。轉換可套用至物件的一部分，而且在轉換前與轉換後套用 `Range` 參數的結果相同。

   相比之下，將 ASCII 編碼物件中的字元反轉的函數不符合這些條件。這類函數滿足標準 1，因為其可以套用於部分物件範圍。但不符合標準 2，因為在轉換前套用 `Range` 參數與轉換後套用參數的結果不同。

   請考慮以下請求：將函數套用至包含內容 `abcdefg` 之物件的前三個字元。在轉換前套用 `Range` 參數會僅擷取 `abc`，接著反轉資料，傳回 `cba`。但是，如果在轉換之後套用參數，函數將擷取整個物件，將其反轉，然後套用 `Range` 參數，最終傳回 `gfe`。因為這些結果都不同，所以此函數不應在從 Amazon S3 擷取物件時套用 `Range` 參數。其反而應該擷取整個物件、執行轉換，然後才套用 `Range` 參數。
**警告**  
在許多情況下，將 `Range` 參數套用至預先簽署的 URL，將導致 Lambda 函數或請求用戶端的發生意外行為。如前文方法 A 中所述，除非確定應用程式在從 Amazon S3 中僅擷取部分物件時能夠正常工作，否則建議您擷取和轉換完整物件。

   如果您的應用程式符合先前在方法 B 中所述的條件，您可以僅擷取請求的物件範圍，然後在該範圍上執行轉換，以簡化 AWS Lambda 函數。

   下列 Java 程式碼範例會示範如何執行下列動作：
   + 從 `GetObject` 請求中擷取 `Range` 標頭。
   + 將 `Range` 標頭新增至 Lambda 可以用來從 Amazon S3 擷取請求範圍的預先簽章 URL。

   ```
   private HttpRequest.Builder applyRangeHeader(ObjectLambdaEvent event, HttpRequest.Builder presignedRequest) {
       var header = event.getUserRequest().getHeaders().entrySet().stream()
               .filter(e -> e.getKey().toLowerCase(Locale.ROOT).equals("range"))
               .findFirst();
   
       // Add check in the query string itself.
       header.ifPresent(entry -> presignedRequest.header(entry.getKey(), entry.getValue()));
       return presignedRequest;
   }
   ```