

# 自定义源的请求和响应行为
<a name="RequestAndResponseBehaviorCustomOrigin"></a>

要了解在使用自定义源时 CloudFront 如何处理请求和响应，请参阅以下部分：

**Topics**
+ [CloudFront 如何处理请求及如何将请求转发给您的自定义源](#RequestBehaviorCustomOrigin)
+ [CloudFront 如何处理自定义源的响应](#ResponseBehaviorCustomOrigin)

## CloudFront 如何处理请求及如何将请求转发给您的自定义源
<a name="RequestBehaviorCustomOrigin"></a>

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

**Contents**
+ [身份验证](#RequestCustomClientAuth)
+ [缓存持续时间和最小 TTL](#RequestCustomCaching)
+ [客户端 IP 地址](#RequestCustomIPAddresses)
+ [客户端 SSL 身份验证](#RequestCustomClientSideSslAuth)
+ [压缩](#RequestCustomCompression)
+ [有条件请求](#RequestCustomConditionalGETs)
+ [Cookies](#RequestCustomCookies)
+ [跨源资源共享 (CORS)](#request-custom-cors)
+ [加密](#RequestCustomEncryption)
+ [包含正文的 GET 请求](#RequestCustom-get-body)
+ [HTTP 方法](#RequestCustomHTTPMethods)
+ [HTTP 请求标头和 CloudFront 行为（自定义源和 Amazon S3 源）](#request-custom-headers-behavior)
+ [HTTP 版本](#RequestCustomHTTPVersion)
+ [请求的最大长度与 URL 的最大长度](#RequestCustomMaxRequestStringLength)
+ [OCSP Stapling](#request-custom-ocsp-stapling)
+ [持久性连接](#request-custom-persistent-connections)
+ [协议](#RequestCustomProtocols)
+ [查询字符串](#RequestCustomQueryStrings)
+ [源连接超时和尝试次数](#custom-origin-timeout-attempts)
+ [源响应超时](#request-custom-request-timeout)
+ [针对同一对象的并发请求（请求折叠）](#request-custom-traffic-spikes)
+ [`User-Agent` 标头](#request-custom-user-agent-header)

### 身份验证
<a name="RequestCustomClientAuth"></a>

如果您将 `Authorization` 标头转发给源，则可将源服务器配置为针对以下类型的请求而请求进行客户端身份验证：
+ `DELETE`
+ `GET`
+ `HEAD`
+ `PATCH`
+ `PUT`
+ `POST`

对于 `OPTIONS` 请求，*仅* 在您使用以下 CloudFront 设置时才可以配置客户端身份验证：
+ 配置 CloudFront 以将 `Authorization` 标头转发到您的源
+ 将 CloudFront 配置为*不* 缓存对 `OPTIONS` 请求的响应

有关更多信息，请参阅 [配置 CloudFront 以转发 `Authorization` 标头](add-origin-custom-headers.md#add-origin-custom-headers-forward-authorization)。

您可以使用 HTTP 或 HTTPS 将请求转发到源服务器。有关更多信息，请参阅 [将 HTTPS 与 CloudFront 结合使用](using-https.md)。

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

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

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

### 客户端 IP 地址
<a name="RequestCustomIPAddresses"></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`

一些应用程序（例如，负载均衡器（包括 Elastic Load Balancing）、Web 应用程序防火墙、反向代理、入侵防御系统以及 API Gateway）会将转发请求的 CloudFront 边缘服务器的 IP 地址附加到 `X-Forwarded-For` 标头的末尾。例如，如果 CloudFront 将 `X-Forwarded-For: 192.0.2.2` 包含在它转发给 ELB 的请求中，并且 CloudFront 边缘服务器的 IP 地址为 192.0.2.199，则 EC2 实例收到的请求将包含以下标头：

`X-Forwarded-For: 192.0.2.2,192.0.2.199`

**注意**  
`X-Forwarded-For` 标头包含 IPv4 地址（例如 192.0.2.44）和 IPv6 地址（例如 2001:0db8:85a3::8a2e:0370:7334）。  
另请注意，当前服务器 (CloudFront) 路径上的每个节点都可以修改 `X-Forwarded-For` 标头。有关更多信息，请参阅 [RFC 7239](https://datatracker.ietf.org/doc/html/rfc7239) 的第 8.1 节。也可以使用 CloudFront 边缘计算函数修改标头。

### 客户端 SSL 身份验证
<a name="RequestCustomClientSideSslAuth"></a>

CloudFront 支持双向 TLS（mTLS）身份验证，在此类身份验证中，客户端和服务器通过证书相互进行身份验证。配置 mTLS 后，CloudFront 可以在 TLS 握手过程中验证客户端证书，也可以选择运行 CloudFront Functions 来实施自定义验证逻辑。

对于在未配置 mTLS 的情况下请求客户端证书的源，CloudFront 会删除该请求。

有关配置 mTLS 的更多信息，请参阅[关联 CloudFront 连接函数](connection-functions.md)。

CloudFront 不支持使用客户端 SSL 证书进行客户端身份验证。如果源要求客户端证书，则 CloudFront 将删除请求。

### 压缩
<a name="RequestCustomCompression"></a>

有关更多信息，请参阅 [提供压缩文件](ServingCompressedFiles.md)。

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

当 CloudFront 从边缘缓存接收已过期对象的请求时，其将请求转发到源，以获取对象的最新版本或获取 CloudFront 边缘缓存已具有最新版本的源的确认。通常，当源最后发送对象到 CloudFront 时，其在响应中包括 `ETag` 值、`LastModified` 值或以上两种值。在 CloudFront 转发到源的新请求中，CloudFront 将添加以下一项或两项内容：
+ `If-Match` 或 `If-None-Match` 标头，其包括对象过期版本的`ETag`值。
+ `If-Modified-Since` 标头，其包含对象过期版本的`LastModified`值。

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

**注意**  
如果将 CloudFront 配置为转发 Cookie（全部或某个子集），则不支持 `If-Modified-Since` 和 `If-None-Match` 条件请求。  
有关更多信息，请参阅 [根据 Cookie 缓存内容](Cookies.md)。

### Cookies
<a name="RequestCustomCookies"></a>

您可配置 CloudFront 以将 cookie 转发到您的源。有关更多信息，请参阅 [根据 Cookie 缓存内容](Cookies.md)。

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

如果您希望 CloudFront 采用跨源资源共享设置，请配置 CloudFront 以将 `Origin` 标头转发到源。有关更多信息，请参阅 [根据请求标头缓存内容](header-caching.md)。

### 加密
<a name="RequestCustomEncryption"></a>

您可以要求查看器使用 HTTPS 将请求发送到 CloudFront，并要求 CloudFront 使用由查看器使用的协议将请求转发到您的自定义源。有关更多信息，请参阅以下分配设置：
+ [查看器协议策略](DownloadDistValuesCacheBehavior.md#DownloadDistValuesViewerProtocolPolicy)
+ [协议（仅自定义源）](DownloadDistValuesOrigin.md#DownloadDistValuesOriginProtocolPolicy)

CloudFront 使用 SSLv3、TLSv1.0、TLSv1.1、TLSv1.2 和 TLSv1.3 协议将 HTTPS 请求转发给原始服务器。对于自定义源，您可以选择您希望 CloudFront 在与源通信时使用的 SSL 协议：
+ 如果您使用 CloudFront 控制台，请使用**源 SSL 协议**复选框选择协议。有关更多信息，请参阅 [创建分配](distribution-web-creating-console.md)。
+ 如果您使用的是 CloudFront API，请使用 `OriginSslProtocols` 元素来指定协议。有关更多信息，请参阅《Amazon CloudFront API 参考》**中的 [OriginSslProtocols](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_OriginSslProtocols.html) 和 [DistributionConfig](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_DistributionConfig.html)。

如果源是 Amazon S3 存储桶，则 CloudFront 将默认为 TLSv1.3。

**重要**  
不支持其他版本的 SSL 和 TLS。

有关将 HTTPS 与 CloudFront 搭配使用的更多信息，请参阅[将 HTTPS 与 CloudFront 结合使用](using-https.md)。有关 CloudFront 支持的用于查看器和 CloudFront 之间以及 CloudFront 和您的源之间的 HTTPS 通信的密码的列表，请参阅[查看器和 CloudFront 之间支持的协议和密码](secure-connections-supported-viewer-protocols-ciphers.md)。

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

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

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

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

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

有关如何配置是否让自定义源处理这些方法的信息，请参阅该源的文档。

**重要**  
如果您将 CloudFront 配置为接受 CloudFront 支持的所有 HTTP 方法并将这些方法转发到您的源，请将您的源服务器配置为处理所有方法。例如，如果因为您想使用 `POST` 而将 CloudFront 配置为接受并转发这些方法，则必须将您的源服务器配置为适当处理 `DELETE` 请求，以便查看器无法删除您不希望其删除的资源。有关更多信息，请参阅您的 HTTP 服务器的文档。

### HTTP 请求标头和 CloudFront 行为（自定义源和 Amazon S3 源）
<a name="request-custom-headers-behavior"></a>

下表列出了 HTTP 请求标头，您可以将其转发到自定义源和 Amazon S3 源（有例外情况需要注意）。对于每个标头，该表包含有关以下内容的信息：
+ 如果您不将 CloudFront 配置为将标头转发给您的源（这会导致 CloudFront 基于标头值缓存您的对象），CloudFront 会做出怎样的行为。
+ 您是否能将 CloudFront 配置为基于标头的标头值缓存对象。

  您可以将 CloudFront 配置为基于 `Date` 和 `User-Agent` 标头中的值缓存对象，但建议您不要这样做。这些标头具有许多可能的值，并且基于其值的缓存操作会导致 CloudFront 将更多请求转发到源。

有关基于标头值的缓存操作的更多信息，请参阅[根据请求标头缓存内容](header-caching.md)。


| 标头 | 在您未将 CloudFront 配置为基于标头值进行缓存时的行为 | 支持基于标头值的缓存操作 | 
| --- | --- | --- | 
|  其他定义的标头  |  **旧缓存设置** – CloudFront 将标头转发到源。  |  是  | 
|  `Accept`  |  CloudFront 删除标头。  |  是  | 
|  `Accept-Charset`  |  CloudFront 删除标头。  |  是  | 
|  `Accept-Encoding`  |  如果值包含 `gzip` 或 `br`，则 CloudFront 会将标准化的 `Accept-Encoding` 标头转发到源。 有关更多信息，请参阅 [压缩支持](cache-key-understand-cache-policy.md#cache-policy-compressed-objects)和 [提供压缩文件](ServingCompressedFiles.md)。  |  是  | 
|  `Accept-Language`  |  CloudFront 删除标头。  |  是  | 
|  `Authorization`  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonCloudFront/latest/DeveloperGuide/RequestAndResponseBehaviorCustomOrigin.html)  |  是  | 
|  `Cache-Control`  |  CloudFront 将标头转发到源。  |  否  | 
|  `CloudFront-Forwarded-Proto`  |  在将请求转发给您的源之前，CloudFront 不会添加标头。 有关更多信息，请参阅 [配置基于请求协议的缓存](header-caching.md#header-caching-web-protocol)。  |  是  | 
|  `CloudFront-Is-Desktop-Viewer`  |  在将请求转发给您的源之前，CloudFront 不会添加标头。 有关更多信息，请参阅 [配置基于设备类型的缓存](header-caching.md#header-caching-web-device)。  |  是  | 
|  `CloudFront-Is-Mobile-Viewer`  |  在将请求转发给您的源之前，CloudFront 不会添加标头。 有关更多信息，请参阅 [配置基于设备类型的缓存](header-caching.md#header-caching-web-device)。  |  是  | 
|  `CloudFront-Is-Tablet-Viewer`  |  在将请求转发给您的源之前，CloudFront 不会添加标头。 有关更多信息，请参阅 [配置基于设备类型的缓存](header-caching.md#header-caching-web-device)。  |  是  | 
|  `CloudFront-Viewer-Country`  |  在将请求转发给您的源之前，CloudFront 不会添加标头。  |  是  | 
|  `Connection`  |  在将请求转发给您的源之前，CloudFront 会将此标头替换为 `Connection: Keep-Alive`。  |  否  | 
|  `Content-Length`  |  CloudFront 将标头转发到源。  |  否  | 
|  `Content-MD5`  |  CloudFront 将标头转发到源。  |  是  | 
|  `Content-Type`  |  CloudFront 将标头转发到源。  |  是  | 
|  `Cookie`  |  如果您将 CloudFront 配置为转发 Cookie，则它会将 `Cookie` 标头字段转发给您的源。如果不这样做，CloudFront 会删除 `Cookie` 标头字段。有关更多信息，请参阅 [根据 Cookie 缓存内容](Cookies.md)。  |  否  | 
|  `Date`  |  CloudFront 将标头转发到源。  |  是，但建议不要这样做  | 
|  `Expect`  |  CloudFront 删除标头。  |  是  | 
|  `From`  |  CloudFront 将标头转发到源。  |  是  | 
|  `Host`  |  CloudFront 将值设置为与请求的对象关联的源的域名。 您无法基于 Amazon S3 或 MediaStore 源的主机标头进行缓存。  |  是 (自定义) 否（S3 和 MediaStore）  | 
|  `If-Match`  |  CloudFront 将标头转发到源。  |  是  | 
|  `If-Modified-Since`  |  CloudFront 将标头转发到源。  |  是  | 
|  `If-None-Match`  |  CloudFront 将标头转发到源。  |  是  | 
|  `If-Range`  |  CloudFront 将标头转发到源。  |  是  | 
|  `If-Unmodified-Since`  |  CloudFront 将标头转发到源。  |  是  | 
|  `Max-Forwards`  |  CloudFront 将标头转发到源。  |  否  | 
|  `Origin`  |  CloudFront 将标头转发到源。  |  是  | 
|  `Pragma`  |  CloudFront 将标头转发到源。  |  否  | 
|  `Proxy-Authenticate`  |  CloudFront 删除标头。  |  否  | 
|  `Proxy-Authorization`  |  CloudFront 删除标头。  |  否  | 
|  `Proxy-Connection`  |  CloudFront 删除标头。  |  否  | 
|  `Range`  |  CloudFront 将标头转发到源。有关更多信息，请参阅 [CloudFront 如何处理对象的部分请求 (Range GET)。](RangeGETs.md)。  |  是 (默认值)  | 
|  `Referer`  |  CloudFront 删除标头。  |  是  | 
|  `Request-Range`  |  CloudFront 将标头转发到源。  |  否  | 
|  `TE`  |  CloudFront 删除标头。  |  否  | 
|  `Trailer`  |  CloudFront 删除标头。  |  否  | 
|  `Transfer-Encoding`  |  CloudFront 将标头转发到源。  |  否  | 
|  `Upgrade`  |  CloudFront 会删除标头，除非您建立了 WebSocket 连接。  |  否（WebSocket 连接除外）  | 
|  `User-Agent`  |  CloudFront 将该标头字段的值替换为 `Amazon CloudFront`。如果您希望 CloudFront 根据用户使用的设备缓存您的内容，请参阅[配置基于设备类型的缓存](header-caching.md#header-caching-web-device)。  |  是，但建议不要这样做  | 
|  `Via`  |  CloudFront 将标头转发到源。  |  是  | 
|  `Warning`  |  CloudFront 将标头转发到源。  |  是  | 
|  `X-Amz-Cf-Id`  |  在将请求转发给您的源之前，CloudFront 会将标头添加到查看器请求。标头值包含一个用于唯一标识请求的加密的字符串。  |  否  | 
|  `X-Edge-*`  |  CloudFront 删除所有 `X-Edge-*` 标头。  |  否  | 
|  `X-Forwarded-For`  |  CloudFront 将标头转发到源。有关更多信息，请参阅 [客户端 IP 地址](#RequestCustomIPAddresses)。  |  是  | 
|  `X-Forwarded-Proto`  |  CloudFront 删除标头。  |  否  | 
|  `X-HTTP-Method-Override`  |  CloudFront 删除标头。  |  是  | 
|  `X-Real-IP`  |  CloudFront 删除标头。  |  否  | 

### HTTP 版本
<a name="RequestCustomHTTPVersion"></a>

CloudFront 使用 HTTP/1.1 将请求转发给您的自定义源。

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

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

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

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

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

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

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

### 持久性连接
<a name="request-custom-persistent-connections"></a>

当 CloudFront 收到来自您的源的响应时，它会尝试将连接保持几秒钟，以防在此时段内有另一个请求到达。保持持久性连接可节省重新建立 TCP 连接以及针对后续请求再次进行 TLS 握手所需的时间。

有关更多信息 (包括如何配置持久性连接)，请参阅[源保持连接超时（仅自定义源和 VPC 源）](DownloadDistValuesOrigin.md#DownloadDistValuesOriginKeepaliveTimeout)一节中的[所有分配设置参考](distribution-web-values-specify.md)。

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

CloudFront 基于以下将 HTTP 或 HTTPS 请求转发到源服务器：
+ 查看器发送到 CloudFront 的请求的协议（HTTP 或 HTTPS）。
+ CloudFront 控制台中**源协议策略**的值，或者，如果您使用 CloudFront API，则为 `OriginProtocolPolicy`复杂型中的 `DistributionConfig` 元素。在 CloudFront 控制台中，选项包括**仅 HTTP**、**仅 HTTPS** 和**匹配查看器**。

如果您指定**仅 HTTP** 或**仅 HTTPS**，则 CloudFront 仅使用指定的协议将请求转发到源服务器，而不考虑查看器请求中的协议。

如果您指定**匹配查看器**，则 CloudFront 将使用查看器请求中的协议将请求转发到源服务器。请注意，CloudFront 仅缓存对象一次，即使查看器使用 HTTP 和 HTTPS 协议发出请求。

**重要**  
如果 CloudFront 使用 HTTPS 协议将请求转发给源，并且源服务器返回无效证书或自签名证书，则 CloudFront 将中断 TCP 连接。

有关使用 CloudFront 控制台如何更新分配的信息，请参阅[更新分配](HowToUpdateDistribution.md)。有关如何使用 CloudFront API 更新分配的信息，请转到《Amazon CloudFront API 参考》**中的 [UpdateDistribution](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_UpdateDistribution.html)。

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

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

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

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

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

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

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

### 源响应超时
<a name="request-custom-request-timeout"></a>

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

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

  

有关更多信息（包括如何配置源响应超时），请参阅[响应超时](DownloadDistValuesOrigin.md#DownloadDistValuesOriginResponseTimeout)。

### 针对同一对象的并发请求（请求折叠）
<a name="request-custom-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 不支持请求折叠。

### `User-Agent` 标头
<a name="request-custom-user-agent-header"></a>

如果您希望 CloudFront 基于用户用来查看内容的设备缓存不同版本的对象，建议您将 CloudFront 配置为将一个或多个以下标头转发给您的自定义源：
+ `CloudFront-Is-Desktop-Viewer`
+ `CloudFront-Is-Mobile-Viewer`
+ `CloudFront-Is-SmartTV-Viewer`
+ `CloudFront-Is-Tablet-Viewer`

根据 `User-Agent` 标头的值，在将请求转发给您的源之前，CloudFront 将这些标头的值设置为 `true` 或 `false`。如果某个设备归入多个类别中，则多个值可能为 `true`。例如，对于一些平板电脑设备，CloudFront 可能将 `CloudFront-Is-Mobile-Viewer` 和 `CloudFront-Is-Tablet-Viewer` 设置为 `true`。有关将 CloudFront 配置为基于请求标头进行缓存的更多信息，请参阅[根据请求标头缓存内容](header-caching.md)。

您可以将 CloudFront 配置为基于 `User-Agent` 标头中的值缓存对象，但建议您不要这样做。`User-Agent` 标头具有许多可能的值，并且根据这些值的缓存操作导致 CloudFront 将更多请求转发到源。

如果未将 CloudFront 配置为根据 `User-Agent` 标头中的值缓存对象，在将请求转发到源之前，CloudFront 将添加具有以下值的 `User-Agent` 标头：

`User-Agent = Amazon CloudFront`

无论来自查看器的请求是否包含 `User-Agent` 标头，CloudFront 都会添加此标头。如果来自查看器的请求包含 `User-Agent` 标头，则 CloudFront 会删除它。

## CloudFront 如何处理自定义源的响应
<a name="ResponseBehaviorCustomOrigin"></a>

了解 CloudFront 如何处理自定义源的响应。

**Contents**
+ [`100 Continue` 响应](#Response100Continue)
+ [缓存](#ResponseCustomCaching)
+ [已取消的请求](#response-custom-canceled-requests)
+ [内容协商](#ResponseCustomContentNegotiation)
+ [Cookie](#ResponseCustomCookies)
+ [中断的 TCP 连接](#ResponseCustomDroppedTCPConnections)
+ [CloudFront 移除或替换的 HTTP 响应标头](#ResponseCustomRemovedHeaders)
+ [最大可缓存文件大小](#ResponseCustomMaxFileSize)
+ [源不可用](#ResponseCustomOriginUnavailable)
+ [重定向](#ResponseCustomRedirects)
+ [`Transfer-Encoding` 标头](#ResponseCustomTransferEncoding)

### `100 Continue` 响应
<a name="Response100Continue"></a>

您的源服务器不能向 CloudFront 发送多个 100-Continue 响应。在第一个 100-Continue 响应之后，CloudFront 需要“HTTP 200 正常”响应。如果您的源服务器在第一个 100-Continue 响应之后又发送了该响应，CloudFront 将返回错误。

### 缓存
<a name="ResponseCustomCaching"></a>
+ 确保源服务器为 `Date` 和 `Last-Modified` 标头字段设置有效、准确的值。
+ CloudFront 通常会遵循来自源的响应中的 `Cache-Control: no-cache` 标头。有关例外，请参阅[针对同一对象的并发请求（请求折叠）](#request-custom-traffic-spikes)。

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

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

### 内容协商
<a name="ResponseCustomContentNegotiation"></a>

如果您的源在响应中返回 `Vary:*`，并且相应缓存行为的**最短 TTL** 的值为 **0**，则 CloudFront 将缓存对象，但仍会将对象的每个后续请求转发到源以确认缓存包含最新版本的对象。CloudFront 不包含任何条件标头，例如 `If-None-Match` 或 `If-Modified-Since`。因此，您的源会将对象返回给 CloudFront 以响应每个请求。

如果您的源在响应中返回 `Vary:*`，并且相应缓存行为的**最短 TTL** 的值为任何其他值，则 CloudFront 将处理 `Vary` 标头，如[CloudFront 移除或替换的 HTTP 响应标头](#ResponseCustomRemovedHeaders)中所述。

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

如果您为缓存行为启用了 cookie，并且如果源返回带对象的 cookie，CloudFront 则缓存对象和 cookie。请注意，这降低了对象的缓存能力。有关更多信息，请参阅 [根据 Cookie 缓存内容](Cookies.md)。

### 中断的 TCP 连接
<a name="ResponseCustomDroppedTCPConnections"></a>

如果在您的源将对象返回给 CloudFront 时，CloudFront 和您的源之间的 TCP 连接中断，CloudFront 行为将取决于您的源是否在响应中包括 `Content-Length` 标头：
+ **Content-Length 标头** – CloudFront 在其从您的源中获得对象时将对象返回给查看器。但是，如果 `Content-Length` 标头的值与对象大小不匹配，CloudFront 则不缓存对象。
+ **Transfer-Encoding: 分块** – 在从源中获取对象时，CloudFront 将对象返回到查看器。但是，如果分块响应未完成，则 CloudFront 不会对该对象进行缓存。
+ **无 Content-Length 标头** – CloudFront 将对象返回给查看器并对其进行缓存，但该对象可能不完整。在没有 `Content-Length` 标头的情况下，CloudFront 无法确定 TCP 连接是否是偶然中断还是有意中断。

建议您配置您的 HTTP 服务器，以添加 `Content-Length` 标头，防止 CloudFront 缓存部分对象。

### CloudFront 移除或替换的 HTTP 响应标头
<a name="ResponseCustomRemovedHeaders"></a>

在将来自您的源的响应转发给查看器之前，CloudFront 将删除或更新以下标头字段：
+ `Set-Cookie` – 如果您将 CloudFront 配置为转发 Cookie，则它会将 `Set-Cookie` 标头字段转发给客户端。有关更多信息，请参阅 [根据 Cookie 缓存内容](Cookies.md)。
+ `Trailer`
+ `Transfer-Encoding` – 如果您的源返回此标头字段，则在将响应返回给查看器之前，CloudFront 会将值设置为 `chunked`。
+ `Upgrade`
+ `Vary` – 请注意以下几点：
  + 如果您将 CloudFront 配置为将任何设备特定的标头转发给您的源 (`CloudFront-Is-Desktop-Viewer`、`CloudFront-Is-Mobile-Viewer`、`CloudFront-Is-SmartTV-Viewer`、`CloudFront-Is-Tablet-Viewer`)，并且您将源配置为将 `Vary:User-Agent` 返回给 CloudFront，则 CloudFront 会将 `Vary:User-Agent` 返回给查看器。有关更多信息，请参阅 [配置基于设备类型的缓存](header-caching.md#header-caching-web-device)。
  + 如果您将源配置为将 `Accept-Encoding` 或 `Cookie` 包含在 `Vary` 标头中，则 CloudFront 会将这些值包含在对查看器的响应中。
  + 如果配置 CloudFront 以将标头转发到源，并且配置源以通过 `Vary` 标头将标头名返回到 CloudFront（如 `Vary:Accept-Charset,Accept-Language`），则 CloudFront 将具有这些值的 `Vary` 标头返回到查看器。
  + 有关 CloudFront 如何处理 `*` 标头中的 `Vary` 值的信息，请参阅[内容协商](#ResponseCustomContentNegotiation)。
  + 如果您将源配置为将任何其他值包含在 `Vary` 标头中，则在将响应返回给查看器之前，CloudFront 将删除这些值。
+ `Via` – 在对查看器的响应中，CloudFront 将值设置为以下内容：

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

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

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

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

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

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

### 源不可用
<a name="ResponseCustomOriginUnavailable"></a>

如果您的源服务器不可用且 CloudFront 收到针对边缘缓存中已过期对象的请求（例如，因为 `Cache-Control max-age` 指令中指定的期限已过），那么 CloudFront 会提供该对象的已过期版本或提供自定义错误页面。有关配置自定义错误页面时 CloudFront 行为的更多信息，请参阅[当您已配置自定义错误页面时 CloudFront​ 如何处理错误](HTTPStatusCodes.md#HTTPStatusCodes-custom-error-pages)。

某些情况下，将逐出很少被请求的对象且不再在边缘缓存中提供。CloudFront 不能提供已被逐出的对象。

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

如果更改对象在源服务器上的位置，您可以配置 Web 服务器以重定向请求到新位置。在您配置重定向后，查看器第一次提交对象请求时，CloudFront 将请求发送到源，源则用重定向（例如 `302 Moved Temporarily`）进行响应。CloudFront 缓存重定向并将其返回给查看器。CloudFront 不遵照重定向。

您可以配置 Web 服务器以将请求重定向到以下位置之一：
+ 对象在原服务器上的新 URL。当查看器按照重定向路线访问新 URL 时，查看器将绕过 CloudFront，直接到达源。因此，建议您不要将请求重定向到对象在源上的新 URL。
+ 对象的新 CloudFront URL。当查看器提交包含新 CloudFront URL 的请求时，CloudFront 将从源上的新位置获取对象，并将其缓存在边缘站点中，然后将该对象返回给查看器。对象随后的请求将由边缘站点提供。这避免了查看器从源请求对象相关的延迟和负载。但是，对象的每个新请求将产生两个 CloudFront 请求的费用。

### `Transfer-Encoding` 标头
<a name="ResponseCustomTransferEncoding"></a>

CloudFront 仅支持 `chunked` 标头的 `Transfer-Encoding` 值。如果您的源返回 `Transfer-Encoding: chunked`，则 CloudFront 会在边缘站点收到对象后将该对象返回给客户端，然后以分块格式将该对象缓存起来以提供给后续请求。

如果查看器发出 `Range GET` 请求，并且源返回 `Transfer-Encoding: chunked`，则 CloudFront 会将整个对象返回给查看器而不是请求的范围。

如果无法预先确定响应的内容长度，建议您使用分块编码。有关更多信息，请参阅 [中断的 TCP 连接](#ResponseCustomDroppedTCPConnections)。