

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

# 如何使用條件式寫入防止物件覆寫
<a name="conditional-writes"></a>

透過使用條件式寫入，您可以將額外的標頭新增至 `WRITE` 請求，以指定 Amazon S3 操作的先決條件。若要有條件地寫入物件，請新增 HTTP `If-None-Match` 或 `If-Match` 標頭。

`If-None-Match` 標頭會驗證您的儲存貯體中不存在具有相同金鑰名稱的物件，以防止覆寫現有資料。

或者，您也可以新增 `If-Match` 標頭，在寫入物件之前檢查物件的實體標籤 (ETag)。透過此標頭，Amazon S3 會將提供的 ETag 值與 S3 中物件的 ETag 值進行比較。如果 ETag 值不相符，操作就會失敗。

儲存貯體擁有者可以使用儲存貯體政策，對上傳的物件強制執行條件式寫入。如需詳細資訊，請參閱[在 Amazon S3 儲存貯體上強制執行條件式寫入](conditional-writes-enforce.md)。

**注意**  
若要使用條件式寫入，您必須使用 AWS Signature 第 4 版來簽署請求。

**Topics**
+ [如何根據金鑰名稱防止物件覆寫](#conditional-write-key-names)
+ [如果物件已變更，如何防止覆寫](#conditional-write-etags)
+ [條件式寫入行為](#conditional-error-response)
+ [條件式寫入案例](#conditional-write-scenarios)
+ [在 Amazon S3 儲存貯體上強制執行條件式寫入](conditional-writes-enforce.md)

## 如何根據金鑰名稱防止物件覆寫
<a name="conditional-write-key-names"></a>

您可以使用 HTTP `If-None-Match`條件式標頭，根據物件的金鑰名稱檢查物件是否已存在於指定的儲存貯體中，然後再建立物件或將其複製到目的地儲存貯體。

使用 HTTP `If-None-Match` 標頭的條件式寫入會在 `WRITE` 操作期間檢查物件是否存在。如果在儲存貯體中找到相同的金鑰名稱，操作就會失敗。如果沒有 HTTP `If-None-Match`標頭，如果您在未版本或版本暫停的儲存貯體中上傳或複製具有相同金鑰名稱的物件，則會覆寫物件。如需使用金鑰名稱的詳細資訊，請參閱[命名 Amazon S3 物件](object-keys.md)。

**注意**  
HTTP `If-None-Match`標頭僅適用於版本儲存貯體中物件的目前版本。

若要使用 HTTP `If-None-Match` 標頭執行條件式寫入，您必須具有 `s3:PutObject` 許可。這可讓呼叫者檢查儲存貯體中是否存在物件。`If-None-Match` 標頭必須有 \* (星號) 值。

您可以搭配下列 API 使用 `If-None-Match` 標頭：
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html)
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html)
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html)

### 使用 的條件式放置 AWS CLI
<a name="conditional-writes-putobject-CLI-key-names"></a>

下列 `put-object` 範例命令會嘗試對金鑰名稱為 `dir-1/my_images.tar.bz2` 的物件執行條件式寫入。

```
aws s3api put-object --bucket {{amzn-s3-demo-bucket}} --key dir-1/my_images.tar.bz2 --body my_images.tar.bz2 --if-none-match "*"       
```

如需詳細資訊，請參閱《AWS CLI 命令參考》**中的 [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/put-object.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/put-object.html)。

如需 的相關資訊 AWS CLI，請參閱[什麼是 AWS Command Line Interface？](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html) *AWS Command Line Interface 《 使用者指南*》中的 。

### 使用 的條件式複製 AWS CLI
<a name="conditional-writes-copyobject-CLI-key-names"></a>

下列`copy-object`範例命令會嘗試將物件複製到具有金鑰名稱為 之物件的條件式寫入的目的地儲存貯體`dir-1/my_images.tar.bz2`。

```
aws s3api copy-object --copy-source {{amzn-s3-demo-bucket}}/key --key dir-1/my_images.tar.bz2 --bucket {{amzn-s3-demo-bucket2}} --if-none-match "*"            
```

如需詳細資訊，請參閱《AWS CLI 命令參考》**中的 [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/copy-object.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/copy-object.html)。

如需 的相關資訊 AWS CLI，請參閱[什麼是 AWS Command Line Interface？](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html) *AWS Command Line Interface 《 使用者指南》*中的 。

### 使用 進行條件式分段上傳 AWS CLI
<a name="conditional-writes-mpu-complete-CLI-key-names"></a>

下列`complete-multipart-upload`範例命令會嘗試使用金鑰名稱為 之物件的條件式寫入來完成分段上傳`dir-1/my_images.tar.bz2`。在此範例中，檔案：// 字首用於從本機資料夾中名為 的檔案載入 JSON 結構`mpustruct`，其中列出已針對 tnis 特定分段上傳上傳的所有組件。

```
aws s3api complete-multipart-upload --multipart-upload file://mpustruct --bucket {{amzn-s3-demo-bucket}} --key dir-1/my_images.tar.bz2 --upload-id {{upload-id}}  --if-none-match "*"             
```

如需詳細資訊，請參閱《AWS CLI 命令參考》**中的 [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/complete-multipart-upload.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/complete-multipart-upload.html)。

如需 的相關資訊 AWS CLI，請參閱[什麼是 AWS Command Line Interface？](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html) *AWS Command Line Interface 《 使用者指南》*中的 。

## 如果物件已變更，如何防止覆寫
<a name="conditional-write-etags"></a>

物件的 ETag 是物件的唯一字串，反映物件內容的變更。您可以使用 `If-Match` 標頭，將 Amazon S3 儲存貯體中物件的 ETag 值與您在 `WRITE` 操作期間提供的 ETag 值進行比較。如果 ETag 值不相符，操作就會失敗。如需 ETag 的詳細資訊，請參閱[使用 Content-MD5 和 ETag 驗證上傳的物件](checking-object-integrity-upload.md#checking-object-integrity-etag-and-md5)。

若要使用 HTTP `If-Match` 標頭執行條件式寫入，您必須具有 `s3:PutObject` 和 `s3:GetObject` 許可。這可讓呼叫者檢查 ETag 並確認儲存貯體中物件的狀態。`If-Match` 標頭必須有字串形式的 ETag 值。

您可以搭配下列 API 使用 `If-Match` 標頭：
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html)
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html)
+ [https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html)

### 使用 的條件式放置 AWS CLI
<a name="conditional-writes-putobject-CLI-etags"></a>

下列 `put-object` 範例命令會嘗試使用提供的 ETag 值 `6805f2cfc46c0f04559748bb039d69ae` 執行條件式寫入。

```
aws s3api put-object --bucket {{amzn-s3-demo-bucket}} --key dir-1/my_images.tar.bz2 --body my_images.tar.bz2 --if-match "{{6805f2cfc46c0f04559748bb039d69ae}}"         
```

如需詳細資訊，請參閱《AWS CLI 命令參考》**中的 [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/put-object.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/put-object.html)。

如需 的相關資訊 AWS CLI，請參閱[什麼是 AWS Command Line Interface？](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html) *AWS Command Line Interface 《 使用者指南*》中的 。

### 使用 的條件式複製 AWS CLI
<a name="conditional-writes-copyobject-CLI-etags"></a>

下列 `copy-object` 範例命令會嘗試使用提供的 ETag 值 `6805f2cfc46c0f04559748bb039d69ae` 執行條件式寫入。

```
aws s3api copy-object --copy-source {{amzn-s3-demo-bucket}}/key --key dir-1/my_images.tar.bz2 --bucket {{amzn-s3-demo-bucket2}} --if-match "{{6805f2cfc46c0f04559748bb039d69ae}}"             
```

如需詳細資訊，請參閱《AWS CLI 命令參考》**中的 [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/copy-object.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/copy-object.html)。

如需 的相關資訊 AWS CLI，請參閱[什麼是 AWS Command Line Interface？](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html) *AWS Command Line Interface 《 使用者指南*》中的 。

### 使用 進行條件式分段上傳 AWS CLI
<a name="conditional-writes-mpu-complete-CLI-etags"></a>

下列`complete-multipart-upload`範例命令會嘗試使用提供的 ETag 值 ，以條件式寫入完成分段上傳`6805f2cfc46c0f04559748bb039d69ae`。在此範例中，檔案：// 字首用於從本機資料夾中名為 的檔案載入 JSON 結構`mpustruct`，其中列出已針對 tnis 特定分段上傳上傳的所有組件。

```
aws s3api complete-multipart-upload --multipart-upload file://mpustruct --bucket {{amzn-s3-demo-bucket}} --key dir-1/my_images.tar.bz2 --upload-id {{upload-id}} --if-match "{{6805f2cfc46c0f04559748bb039d69ae}}"             
```

如需詳細資訊，請參閱《AWS CLI 命令參考》**中的 [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/complete-multipart-upload.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/complete-multipart-upload.html)。

如需 的相關資訊 AWS CLI，請參閱[什麼是 AWS Command Line Interface？](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html) *AWS Command Line Interface 《 使用者指南*》中的 。

## 條件式寫入行為
<a name="conditional-error-response"></a>

**具有`If-None-Match`標頭的條件式寫入或複本**  
使用 `If-None-Match` 標頭的條件式寫入會根據儲存貯體中的現有物件進行評估。如果儲存貯體中不存在具有相同金鑰名稱的現有物件，則寫入操作會成功並產生 `200 OK` 回應。如果存在現有物件，則寫入操作會失敗並顯示 `412 Precondition Failed` 回應。  
對於已啟用版本控制的儲存貯體，如果不存在具有相同名稱的目前物件版本，或者目前的物件版本是刪除標記，則寫入操作會成功。否則會導致寫入操作失敗並顯示 `412 Precondition Failed` 回應。  
如果相同物件名稱發生多個條件式寫入或副本，則完成的第一個寫入操作會成功。然後，Amazon S3 的後續寫入會失敗並顯示 `412 Precondition Failed` 回應。  
在並行請求的情況下，如果對物件的刪除請求在該物件的條件式寫入操作完成之前成功，您還可能會收到 `409 Conflict` 回應。搭配 `PutObject` 使用條件式寫入時，可能會在收到 `409 Conflict` 錯誤之後重試上傳。使用 `CompleteMultipartUpload` 時，必須使用 `CreateMultipartUpload` 重新啟動整個分段上傳，才能在收到 `409 Conflict` 錯誤之後再次上傳物件。

**具有 `If-Match`標頭的條件式寫入或副本**  
`If-Match` 標頭會根據儲存貯體中的現有物件進行評估。如果不存在具有相同金鑰名稱和相符 ETag 的現有物件，則寫入操作會成功並產生 `200 OK` 回應。如果 ETag 不相符，則寫入操作會失敗並顯示 `412 Precondition Failed` 回應。  
在並行請求的情況下，您還可能會收到 `409 Conflict` 回應。  
如果對物件的並行刪除請求在該物件的條件式寫入操作完成之前成功，您將會收到 `404 Not Found` 回應，因為物件金鑰不再存在。您應該在收到 `404 Not Found` 回應時重新上傳物件。  
如果不存在具有相同名稱的目前物件版本，或者目前的物件版本是刪除標記，則操作會失敗並顯示 `404 Not Found` 錯誤。

## 條件式寫入案例
<a name="conditional-write-scenarios"></a>

請考慮以下兩個用戶端正在對同一儲存貯體執行操作的案例。

**分段上傳期間的條件式寫入**  
條件式寫入不會考慮任何進行中的分段上傳請求，因為這些請求尚未完全寫入物件。請考慮下列範例，其中用戶端 1 正在使用分段上傳來上傳物件。在分段上傳期間，用戶端 2 能夠使用條件式寫入操作成功寫入相同的物件。之後，當用戶端 1 嘗試使用條件式寫入來完成分段上傳時，上傳失敗。

**注意**  
此案例會針對 `If-None-Match` 和 `If-Match` 標頭產生 `412 Precondition Failed` 回應。

![兩個用戶端使用相同金鑰名稱寫入項目的範例。一個使用 UploadPart 進行 MPU，另一個使用 PutObject 和條件式寫入。之後啟動的 CompleteMultipartUpload 操作會失敗。](http://docs.aws.amazon.com/zh_tw/AmazonS3/latest/userguide/images/conwrite_put_mpu.png)


**分段上傳期間的並行刪除**  
如果刪除請求在條件式寫入請求完成之前成功，Amazon S3 會針對寫入操作傳回 `409 Conflict` 或 `404 Not Found` 回應。這是因為先前啟動的刪除請求會優先於條件式寫入操作。在這種情況下，您必須啟動新的分段上傳。

**注意**  
此案例會針對 `If-None-Match` 標頭產生 `409 Conflict` 回應，並針對 `If-Match` 標頭產生 `404 Not Found` 回應。

![兩個用戶端的範例，一個使用分段上傳，另一個在 MPU 開始之後傳送刪除請求。刪除請求在條件式寫入開始之前完成。](http://docs.aws.amazon.com/zh_tw/AmazonS3/latest/userguide/images/conwrite_delete_mpu.png)


**注意**  
為了將儲存費用降至最低，建議您使用 `AbortIncompleteMultipartUpload` 動作，將生命週期規則設定為在指定天數後刪除不完整的分段上傳。如需詳細了解生命週期規則的建立，以刪除不完整分段上傳，請參閱[設定儲存貯體生命週期組態，刪除不完整分段上傳](https://docs.aws.amazon.com/AmazonS3/latest/userguide/mpu-abort-incomplete-mpu-lifecycle-config.html)。