

# 如何执行有条件删除
<a name="conditional-deletes"></a>

您可以使用有条件删除在删除对象之前评估对象是否存在或未更改。您可以在 S3 通用存储桶和目录存储桶中使用 `DeleteObject` 或 `DeleteObjects` API 操作执行有条件删除。首先，在发出有条件删除请求时，您可以使用带有前提条件值 `*` 的 `HTTP If-Match` 标头来检查对象是否存在，或者使用带有您提供的 `ETag` 的 `If-Match` 标头来检查对象是否已修改。

您可以使用 S3 存储桶或 Identity and Access Management（IAM）策略在通用存储桶级别执行有条件删除。有关更多信息，请参阅 [对 Amazon S3 存储桶强制执行有条件删除](conditional-delete-enforce.md)。

**注意**  
有条件删除评估仅适用于对象的当前版本。

**Topics**
+ [如何在删除对象之前检查它是否已修改](#conditional-deletes-etags)
+ [如何在删除对象之前检查它是否存在](#conditional-delete)
+ [对 Amazon S3 存储桶强制执行有条件删除](conditional-delete-enforce.md)

## 如何在删除对象之前检查它是否已修改
<a name="conditional-deletes-etags"></a>

 通过有条件删除，您可以保护应用程序免受意外删除对象的影响。您可以使用带有 `ETag` 值的 `HTTP If-Match` 标头来检查对象是否已修改。如果 S3 存储桶中某个对象的 `ETag` 值与您在删除操作期间提供的 `ETag` 不匹配，则该操作将失败。要使用 `DeleteObjects` 操作有条件地删除多个对象，必须在 XML 请求正文中该对象的 `ETag` 元素中提供 `ETag` 值。有关更多信息，请参阅 [使用 Content-MD5 和 ETag 验证上传的对象](checking-object-integrity-upload.md#checking-object-integrity-etag-and-md5)。

**注意**  
要使用带有 `ETag` 值的 `If-Match` 标头执行有条件删除，您必须具有 `s3:DeleteObject` 和 `s3:GetObject` 权限。

带有 `ETag` 值的 `If-Match` 标头会针对存储桶中的现有对象进行评估。如果存在具有相同键名称和匹配 `ETag` 的现有对象，则 `DeleteObject` 请求将成功并返回 `204 No content` 响应。如果 `ETag` 不匹配，则删除操作将失败并导致 `412 Precondition Failed` 响应。要使用 `DeleteObjects` 操作有条件地删除多个对象，可以在 XML 请求正文中对象的 `ETag` 元素中提供 `ETag` 值。如果请求获得成功，则 `DeleteObjects` 操作将使用 `200 OK` 进行响应，并在响应正文中提供每个对象的状态。如果前提条件成功，则将在响应正文的 `<Deleted>` 元素中捕获该对象的响应。如果前提条件失败，则将在响应正文的 `<Error>` 元素中捕获该对象的响应。

 如果在针对某个对象的有条件删除操作完成之前，对于该对象的 `DELETE` 或 `PUT` 请求获得成功，则在并发请求的情况下也可能收到 `409 Conflict` 错误响应。如果在针对对象的有条件写入操作完成之前，对于对象的并发删除请求获得成功，您将收到 `404 Not Found` 响应，因为对象键不再存在。

您可以将具有 `ETag` 值的 `If-Match` 标头用于以下 API：
+ [https://docs.amazonaws.cn/AmazonS3/latest/API/API_DeleteObject.html](https://docs.amazonaws.cn/AmazonS3/latest/API/API_DeleteObject.html)
+ [https://docs.amazonaws.cn/AmazonS3/latest/API/API_DeleteObjects.html](https://docs.amazonaws.cn/AmazonS3/latest/API/API_DeleteObjects.html)

### 使用 Amazon CLI
<a name="conditional-deletes-deleteobject-CLI-etags"></a>

以下 `delete-object` 示例命令尝试使用提供的 ETag 值 `6805f2cfc46c0f04559748bb039d69al` 执行有条件删除。

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

有关更多信息，请参阅《Amazon CLI Command Reference》**中的 [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/delete-object.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/delete-object.html)。

以下 `delete-objects` 示例命令尝试使用提供的 ETag 值 `6805f2cfc46c0f04559748bb039d69al` 执行有条件删除。

```
aws s3api delete-objects --bucket {{amzn-s3-demo-bucket}} --delete '{"Objects":[{"Key":"my_images.tar.bz2", "ETag": "6805f2cfc46c0f04559748bb039d69al"}]}' 
```

有关更多信息，请参阅《Amazon CLI Command Reference》**中的 [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/delete-objects.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/delete-objects.html)。

有关 Amazon CLI 的更多信息，请参阅《*Amazon Command Line Interface 用户指南*》中的[什么是 Amazon Command Line Interface？](https://docs.amazonaws.cn/cli/latest/userguide/cli-chap-welcome.html)。

## 如何在删除对象之前检查它是否存在
<a name="conditional-delete"></a>

 在尝试删除对象之前，您可以使用带有 `*` 值的 `If-Match` 标头来检查对象是否存在。`*` 值表示只有在对象存在时才应继续执行操作，无论该对象是否已修改。

删除标记是受版本控制的 S3 通用存储桶中的特殊对象，表示对象已被删除。它们是占位符，旨在保留先前版本的同时，使对象显示为已删除。因此，当您将 `If-Match:*` 与 `DeleteObject` API 结合使用时，只有在对象存在的情况下，操作才会成功并显示 `204 No Content`。如果对象的最新版本是删除标记，则该对象不存在，`DeleteObject` API 将失败并返回 `412 Precondition Failed` 响应。有关删除标记的更多信息，请参阅[使用删除标记](DeleteMarker.md)。

要使用 `DeleteObjects` 操作有条件地删除多个对象，可以在 XML 请求正文中对象的 `ETag` 元素中提供 `*`。如果前提条件成功，则 `DeleteObjects` 操作将使用 `200 OK` 进行响应，并在响应正文中提供每个对象的状态。如果前提条件成功，则将在响应正文的 `<Deleted>` 元素中捕获该对象的响应。如果前提条件失败，则将在响应正文的 `<Error>` 元素中捕获该对象的响应。如果在评估任一前提条件时对象不存在，则 S3 会拒绝请求并返回 `Not Found` 错误响应。

**注意**  
 要使用 `If-Match:*` 执行有条件删除，您必须拥有 `s3:DeleteObject` 权限。

您可以将具有 `*` 值的 `If-Match` 标头用于以下 API：
+ [https://docs.amazonaws.cn/AmazonS3/latest/API/API_DeleteObject.html](https://docs.amazonaws.cn/AmazonS3/latest/API/API_DeleteObject.html)
+ [https://docs.amazonaws.cn/AmazonS3/latest/API/API_DeleteObjects.html](https://docs.amazonaws.cn/AmazonS3/latest/API/API_DeleteObjects.html)

### 使用 Amazon CLI
<a name="conditional-deleteobject-CLI-etags"></a>

以下 `delete-object` 示例命令尝试对键名称为 `{{my_images.tar.bz2}}` 且值为 `*`（表示任何 ETag）的对象执行有条件删除。

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

有关更多信息，请参阅《Amazon CLI Command Reference》**中的 [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/delete-object.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/delete-object.html)。

以下 `delete-objects` 示例命令尝试对键名称为 `{{my_images.tar.bz2}}` 且值为 `*`（表示任何 ETag）的对象执行有条件删除。

```
aws s3api delete-objects --bucket {{amzn-s3-demo-bucket}} --delete '{"Objects":[{"Key":"{{my_images.tar.bz2}}", "ETag": "{{*}}"}]}' 
```

有关更多信息，请参阅《Amazon CLI Command Reference》**中的 [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/delete-objects.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/delete-objects.html)。

有关 Amazon CLI 的更多信息，请参阅《*Amazon Command Line Interface 用户指南*》中的[什么是 Amazon Command Line Interface？](https://docs.amazonaws.cn/cli/latest/userguide/cli-chap-welcome.html)。