

# Amazon S3 源的请求和响应行为
<a name="RequestAndResponseBehaviorS3Origin"></a>

要了解在使用 Amazon S3 作为源时 CloudFront 如何处理请求和响应，请参阅以下部分：

**Topics**
+ [

## CloudFront 如何处理请求并将请求转发到您的 Amazon S3 源
](#RequestBehaviorS3Origin)
+ [

## CloudFront 如何处理来自 Amazon S3 源的响应
](#ResponseBehaviorS3Origin)

## CloudFront 如何处理请求并将请求转发到您的 Amazon S3 源
<a name="RequestBehaviorS3Origin"></a>

了解 CloudFront 如何处理查看器请求以及如何将请求转发到您的 Amazon S3 源。

**Contents**
+ [

### 缓存持续时间和最小 TTL
](#RequestS3Caching)
+ [

### 客户端 IP 地址
](#RequestS3IPAddresses)
+ [

### 有条件 GET 请求
](#RequestS3ConditionalGETs)
+ [

### Cookie
](#RequestS3Cookies)
+ [

### 跨源资源共享 (CORS)
](#RequestS3-cors)
+ [

### 包含正文的 GET 请求
](#RequestS3-get-body)
+ [

### HTTP 方法
](#RequestS3HTTPMethods)
+ [

### CloudFront 删除或更新的 HTTP 请求标头
](#request-s3-removed-headers)
+ [

### 请求的最大长度与 URL 的最大长度
](#RequestS3MaxRequestStringLength)
+ [

### OCSP Stapling
](#request-s3-ocsp-stapling)
+ [

### 协议
](#RequestS3Protocol)
+ [

### 查询字符串
](#RequestS3QueryStrings)
+ [

### 源连接超时和尝试次数
](#s3-origin-timeout-attempts)
+ [

### 源响应超时
](#RequestS3RequestTimeout)
+ [

### 针对同一对象的并发请求（请求折叠）
](#request-s3-traffic-spikes)

### 缓存持续时间和最小 TTL
<a name="RequestS3Caching"></a>

要控制对象在 CloudFront 缓存中保留多长时间后 CloudFront 便会将另一请求转发到您的源，您可以：
+ 配置您的源，以添加 `Cache-Control` 或 `Expires` 标题字段到每个对象。
+ 在 CloudFront 缓存行为中指定最短 TTL 的值。
+ 使用默认值 24 小时。

有关更多信息，请参阅 [管理内容保留在缓存中的时间长度（过期）](Expiration.md)。

### 客户端 IP 地址
<a name="RequestS3IPAddresses"></a>

如果查看器将请求发送到 CloudFront 且不包含 `X-Forwarded-For` 请求标头，则 CloudFront 将从 TCP 连接获取查看器的 IP 地址，添加包含该 IP 地址的 `X-Forwarded-For` 标头，并将请求转发到源。例如，如果 CloudFront 从 TCP 连接获取的 IP 地址为 `192.0.2.2`，则它会将以下标头转发到源：

`X-Forwarded-For: 192.0.2.2`

如果查看器将请求发送到 CloudFront 且包含 `X-Forwarded-For` 请求标头，则 CloudFront 将从 TCP 连接获取查看器的 IP 地址，将该 IP 地址附加到 `X-Forwarded-For` 标头的末尾，并将请求转发到源。例如，如果查看器请求包含 `X-Forwarded-For: 192.0.2.4,192.0.2.3`，并且 CloudFront 从 TCP 连接获取的 IP 地址为 `192.0.2.2`，则它会将以下标头转发到源：

`X-Forwarded-For: 192.0.2.4,192.0.2.3,192.0.2.2`

**注意**  
`X-Forwarded-For` 标头包含 IPv4 地址（例如 192.0.2.44）和 IPv6 地址（例如 2001:0db8:85a3::8a2e:0370:7334）。

### 有条件 GET 请求
<a name="RequestS3ConditionalGETs"></a>

当 CloudFront 收到的请求针对的是边缘缓存中已过期的对象时，它将请求转发到 Amazon S3 源，以获取对象的最新版本，或者从 Amazon S3 获取 CloudFront 边缘缓存已有最新版本的确认。当 Amazon S3 最初发送对象到 CloudFront 时，其在响应中包括 `ETag` 值和 `LastModified` 值。在 CloudFront 转发到 Amazon S3 的新请求中，CloudFront 添加以下一个或两个标头：
+ `If-Match` 或 `If-None-Match` 标头，其中包括对象过期版本的 `ETag` 值。
+ `If-Modified-Since` 标头，其中包含对象过期版本的 `LastModified` 值。

Amazon S3 使用此信息来确定对象是否已更新，以及是否将整个对象返回到 CloudFront 或只返回 HTTP 304 状态码（未修改）。

### Cookie
<a name="RequestS3Cookies"></a>

Amazon S3 不处理 Cookie。如果您配置缓存行为，以将 cookie 转发到 Amazon S3 源，CloudFront 将转发 cookie 而 Amazon S3 则会忽略他们。同一对象的所有将来请求 (无论您是否更改 Cookie) 都将通过缓存中的现有对象提供。

### 跨源资源共享 (CORS)
<a name="RequestS3-cors"></a>

如果您希望 CloudFront 尊重 Amazon S3 跨源资源共享设置，请将 CloudFront 配置为将所选标头转发到 Amazon S3。有关更多信息，请参阅 [根据请求标头缓存内容](header-caching.md)。

### 包含正文的 GET 请求
<a name="RequestS3-get-body"></a>

如果查看器 `GET` 请求包含正文，则 CloudFront 将 HTTP 状态代码 403（禁止）返回给查看器。

### HTTP 方法
<a name="RequestS3HTTPMethods"></a>

如果您将 CloudFront 配置为处理其支持的所有 HTTP 方法，则 CloudFront 会接受来自查看器的以下请求，并将这些请求转发给您的 Amazon S3 源：
+ `DELETE`
+ `GET`
+ `HEAD`
+ `OPTIONS`
+ `PATCH`
+ `POST`
+ `PUT`

CloudFront 始终缓存对 `GET` 和 `HEAD` 请求的响应。您也可以将 CloudFront 配置为缓存对 `OPTIONS` 请求的响应。CloudFront 不缓存对使用其他方法的请求的响应。

如果您想使用多部分上传方式将对象添加到 Amazon S3 存储桶，则必须将 CloudFront 源访问控制（OAC）添加到您的分配中，并向 OAC 授予所需的许可。有关更多信息，请参阅 [限制对 Amazon S3 源的访问](private-content-restricting-access-to-s3.md)。

**重要**  
如果您将 CloudFront 配置为接受 CloudFront 支持的所有 HTTP 方法并将这些方法转发到 Amazon S3，则必须创建一个 CloudFront OAC 以限制对您 Amazon S3 内容的访问，并为该 OAC 授予所需的权限。例如，如果因为您想使用 `PUT` 方法而将 CloudFront 配置为接受并转发这些方法，则必须配置 Amazon S3 存储桶策略来适当地处理 `DELETE` 请求，这样查看器就无法删除您不希望其删除的资源。有关更多信息，请参阅 [限制对 Amazon S3 源的访问](private-content-restricting-access-to-s3.md)。

有关 Amazon S3 所支持的操作的信息，请参阅 [Amazon S3 文档](https://docs.aws.amazon.com/s3/index.html)。

### CloudFront 删除或更新的 HTTP 请求标头
<a name="request-s3-removed-headers"></a>

在将请求转发到 Amazon S3 源之前，CloudFront 将删除或更新一些标头。对于大多数标头，此行为与自定义源的相同。有关 HTTP 请求标头的完整列表以及 CloudFront 如何处理这些标头，请参阅[HTTP 请求标头和 CloudFront 行为（自定义源和 Amazon S3 源）](RequestAndResponseBehaviorCustomOrigin.md#request-custom-headers-behavior)。

### 请求的最大长度与 URL 的最大长度
<a name="RequestS3MaxRequestStringLength"></a>

请求的最大长度，包括路径、查询字符串（如果有）以及标头，是 20480 个字节。

CloudFront 根据请求来构造 URL。此 URL 的最大长度是 8192 个字节。

如果请求或 URL 超出最大长度，则 CloudFront 将 HTTP 状态代码 413（请求实体过大）返回到查看器，然后终止与查看器的 TCP 连接。

### OCSP Stapling
<a name="request-s3-ocsp-stapling"></a>

当查看器提交对象的 HTTPS 请求时，CloudFront 或查看器必须与证书颁发机构（CA，Certificate Authority）确认尚未吊销域的 SSL 证书。OCSP Stapling 允许 CloudFront 验证证书并缓存来自 CA 的响应，这将使客户端无需直接向 CA 验证证书，从而加快证书验证速度。

当 CloudFront 收到对同一域中对象的大量 HTTPS 请求时，OCSP Stapling 的性能改进会更明显。CloudFront 边缘站点中的每台服务器必须提交一个单独的验证请求。当 CloudFront 收到对同一个域的大量 HTTPS 请求时，边缘站点中的每台服务器很快将收到来自 CA 的响应，表示它可固定到 SSL 握手中的数据包。当查看器确认证书有效时，CloudFront 可以提供请求的对象。如果您的分配未在 CloudFront 边缘站点中产生大量流量，则新请求更有可能定向到尚未向 CA 验证证书的服务器。在这种情况下，查看器将单独执行验证步骤，并且 CloudFront 服务器将提供对象。该 CloudFront 服务器还会向 CA 提交验证请求，因此，在它下次收到包含同一域名的请求时，便已获得来自 CA 的验证响应。

### 协议
<a name="RequestS3Protocol"></a>

CloudFront 根据查看器请求的协议（HTTP 或 HTTPS），来向源服务器转发 HTTP 或 HTTPS 请求。

**重要**  
如果您的 Amazon S3 存储桶配置为网站终端节点，则您无法将 CloudFront 配置为使用 HTTPS 与您的源进行通信，因为 Amazon S3 不支持该配置中的 HTTPS 连接。

### 查询字符串
<a name="RequestS3QueryStrings"></a>

您可配置 CloudFront 是否将查询字符串参数转发到您的 Amazon S3 源。有关更多信息，请参阅 [根据查询字符串参数缓存内容](QueryStringParameters.md)。

### 源连接超时和尝试次数
<a name="s3-origin-timeout-attempts"></a>

*源连接超时* 是 CloudFront 在尝试建立与源的连接时等待的秒数。

*源连接尝试* 是 CloudFront 尝试连接到源的次数。

这些设置共同决定了在故障转移到辅助源（对于源组）或向查看器返回错误响应之前，CloudFront 尝试连接源的时间。默认情况下，CloudFront 在尝试连接到辅助源或返回错误响应之前等待长达 30 秒（3 次尝试，每次 10 秒）。您可以通过指定更短的连接超时和/或更少的尝试次数来减少此时间。

有关更多信息，请参阅 [控制源超时和尝试次数](high_availability_origin_failover.md#controlling-attempts-and-timeouts)。

### 源响应超时
<a name="RequestS3RequestTimeout"></a>

*源响应超时*（也称为*源读取超时* 或*源请求超时*）同时适用于以下两种情况：
+ CloudFront 在将请求转发到源后等待响应的时间长度（以秒为单位）。
+ CloudFront 从收到来自源的响应的一个数据包到收到下一个数据包之间等待的时间长度（以秒为单位）。

CloudFront 行为取决于查看器请求的 HTTP 方法：
+ `GET` 和 `HEAD` 请求 – 如果源在 30 秒内未响应或停止响应达 30 秒，则 CloudFront 中断连接。如果指定的[源连接尝试次数](DownloadDistValuesOrigin.md#origin-connection-attempts)超过 1 次，CloudFront 将再次尝试获取完整响应。CloudFront 最多尝试 3 次，具体取决于*源连接尝试次数* 设置的值。如果在最终尝试期间，源未进行响应，则 CloudFront 将不会重试，直至它收到对同一个源上的内容的其他请求。
+ `DELETE`、`OPTIONS`、`PATCH`、`PUT` 和 `POST` 请求 – 如果源在 30 秒内未做出响应，CloudFront 将中断连接并且不会再次尝试以联系源。如有必要，客户端可以重新提交请求。

您无法更改 Amazon S3 源（*未* 配置为静态网站托管的 S3 存储桶）的响应超时。

### 针对同一对象的并发请求（请求折叠）
<a name="request-s3-traffic-spikes"></a>

如果 CloudFront 边缘站点收到对于某个对象的请求，而该对象不在缓存中或缓存的对象已过期，则 CloudFront 会立即将请求发送到源。但是，如果存在针对同一对象的并发请求，也就是说，如果在 CloudFront 收到对第一个请求的响应之前，对同一个对象（具有相同缓存密钥）的其他请求到达边缘站点，则 CloudFront 会在将其他请求转发到源之前暂停。这一短暂的暂停有助于减少源上的负载。CloudFront 会将来自原始请求的响应发送到它在暂停期间收到的所有请求。这称为*请求折叠*。在 CloudFront 日志中，第一个请求在 `x-edge-result-type` 字段中标识为 `Miss`，而折叠的请求标识为 `Hit`。有关 CloudFront 日志的更多信息，请参阅[CloudFront 和边缘函数日志记录](logging.md)。

CloudFront 只折叠共享[*缓存键*](understanding-the-cache-key.md) 的请求。如果其他请求不共享相同的缓存键（例如，因为您将 CloudFront 配置为基于请求标头、Cookie 或查询字符串进行缓存），则 CloudFront 会将所有带唯一缓存键的请求转发到您的源。

如果您希望阻止所有请求折叠，则可使用托管式缓存策略 `CachingDisabled`，该策略还可阻止缓存。有关更多信息，请参阅 [使用托管式缓存策略](using-managed-cache-policies.md)。

如果要阻止特定对象的请求折叠，您可以将缓存行为的最小 TTL 设置为 0，*并*配置源以发送 `Cache-Control: private`、`Cache-Control: no-store`、`Cache-Control: no-cache`、`Cache-Control: max-age=0` 或 `Cache-Control: s-maxage=0`。这些配置将会增加源上的负载，并为 CloudFront 等待对第一个请求的响应时暂停的并发请求带来额外的延迟。

**重要**  
目前，如果您在[缓存策略](controlling-the-cache-key.md)、[源请求策略](controlling-origin-requests.md)或旧版缓存设置中启用 Cookie 转发，则 CloudFront 不支持请求折叠。

## CloudFront 如何处理来自 Amazon S3 源的响应
<a name="ResponseBehaviorS3Origin"></a>

了解 CloudFront 如何处理来自 Amazon S3 源的响应。

**Contents**
+ [

### 已取消的请求
](#response-s3-canceled-requests)
+ [

### CloudFront 删除或更新的 HTTP 响应标头
](#response-s3-removed-headers)
+ [

### 最大可缓存文件大小
](#ResponseS3MaxFileSize)
+ [

### 重定向
](#ResponseS3Redirects)

### 已取消的请求
<a name="response-s3-canceled-requests"></a>

如果对象不在边缘缓存中，或者在 CloudFront 从您的源获取对象后，还未来得及传送请求的对象，查看器便终止了会话（例如关闭浏览器），则 CloudFront 不会将该对象缓存到边缘站点中。

### CloudFront 删除或更新的 HTTP 响应标头
<a name="response-s3-removed-headers"></a>

在将来自 Amazon S3 源的响应转发给查看器之前，CloudFront 将删除或更新以下标头字段：
+ `X-Amz-Id-2`
+ `X-Amz-Request-Id`
+ `Set-Cookie` – 如果您将 CloudFront 配置为转发 Cookie，则它会将 `Set-Cookie` 标头字段转发给客户端。有关更多信息，请参阅 [根据 Cookie 缓存内容](Cookies.md)。
+ `Trailer`
+ `Transfer-Encoding` – 如果您的 Amazon S3 源返回此标头字段，则在将响应返回给查看器之前，CloudFront 会将值设置为 `chunked`。
+ `Upgrade`
+ `Via` – 在对查看器的响应中，CloudFront 将值设置为以下内容：

  `Via: `*http-version* *alphanumeric-string*`.cloudfront.net (CloudFront)`

  例如，该值类似以下内容：

  `Via: 1.1 1026589cc7887e7a0dc7827b4example.cloudfront.net (CloudFront)`

### 最大可缓存文件大小
<a name="ResponseS3MaxFileSize"></a>

CloudFront 在其缓存中保存的响应正文的最大大小为 50 GB。这包括未指定 `Content-Length` 标头值的分块传输响应。

您可以使用范围请求将对象分为每个为 50 GB 或以下的段进行请求，从而使用 CloudFront 缓存大于此大小的对象。CloudFront 将会缓存这些段，因为每个段的大小都为 50 GB 或以下。查看器检索完对象的所有段后，可以重建更大的原始对象。有关更多信息，请参阅 [使用范围请求缓存大型对象](RangeGETs.md#cache-large-objects-with-range-requests)。

### 重定向
<a name="ResponseS3Redirects"></a>

您可配置 Amazon S3 存储桶以将所有请求重定向到另一个主机名称；这可能是另一个 Amazon S3 存储桶或 HTTP 服务器。如果您配置存储桶以重定向所有请求且该存储桶是 CloudFront 分配的源，建议您使用分配的域名（例如，d111111abcdef8.cloudfront.net）或与分配（例如，example.com）有关的备用域名 (CNAME) 将存储桶配置为将所有请求重定向到 CloudFront 分配。否则，查看器请求会绕过 CloudFront，直接从新源提供对象。

**注意**  
如果您重定向请求到备用域名，您还必须通过添加 CNAME 记录为您的域更新 DNS 服务。有关更多信息，请参阅 [通过添加备用域名（CNAME）使用自定义 URL](CNAMEs.md)。

这是在您配置重定向所有请求的存储桶时所发生的：

1. 查看器（例如，浏览器）从 CloudFront 请求对象。

1. CloudFront 将请求转发到 Amazon S3 存储桶，而该存储桶是分配的源。

1. Amazon S3 返回 HTTP 状态码 301（永久移走）以及新位置。

1. CloudFront 缓存重定向的状态码和新位置，并将值返回给查看器。CloudFront 没有遵照重定向以从新位置获取对象。

1. 查看器发送对象的另一个请求，但查看器此次指定了其从 CloudFront 获取的新位置：
   + 如果 Amazon S3 存储桶使用分配的域名或备用域名将所有请求重定向到 CloudFront 分配，则 CloudFront 从新位置中的 Amazon S3 存储桶或 HTTP 服务器请求对象。当新位置返回对象时，CloudFront 将其返回给查看器并将其缓存在边缘站点。
   + 如果 Amazon S3 存储桶将请求重定向到另一个位置，第二个请求将绕过 CloudFront。新位置中的 Amazon S3 存储桶或 HTTP 服务器直接将对象返回给查看器，因此，对象从未在 CloudFront 边缘缓存中进行缓存。