

# 了解缓存策略
<a name="cache-key-understand-cache-policy"></a>

利用缓存策略，您可以通过控制缓存键中包含的值（URL 查询字符串、HTTP 标头和 Cookie）来提高缓存命中率。CloudFront 为常见使用案例提供了一些预定义的源请求策略（称为*托管策略*）。您可以使用这些托管策略，也可以创建特定于您的需求的缓存策略。有关托管策略的更多信息，请参阅[使用托管式缓存策略](using-managed-cache-policies.md)。

缓存策略包含以下设置，这些设置的分类如下：*策略信息*、*生存时间 (TTL) 设置*和*缓存键设置*。

## 策略信息
<a name="cache-key-understand-cache-policy-info"></a>

**名称**  
用于标识缓存策略的名称。在控制台中，可以使用名称将缓存策略附加到缓存行为。

**说明**  
用于描述缓存策略的注释。虽然此选项是可选的，但它可以帮助您确定缓存策略的用途。

## 生存时间 (TTL) 设置
<a name="cache-key-understand-cache-policy-ttl"></a>

将生存时间（TTL）设置与 `Cache-Control` 和 `Expires` HTTP 标头（如果它们在源响应中）配合使用，可以确定 CloudFront 缓存中的对象保持有效的时间。

**最小 TTL**  
您希望对象在 CloudFront 缓存中保留的最短时间（以秒为单位），在此时间之后，CloudFront 会向您的源转发另一个请求以确定此对象是否已更新。有关更多信息，请参阅 [管理内容保留在缓存中的时间长度（过期）](Expiration.md)。  
如果最小 TTL 大于 0，CloudFront 将至少在缓存策略的最小 TTL 中指定的持续时间内缓存内容，即使源标头中存在 `Cache-Control: no-cache`、`no-store` 或 `private` 指令也是如此。

**最大 TTL**  
在 CloudFront 向源发送另一个请求以查看对象是否已更新之前，对象在 CloudFront 缓存中保留的最大时间量（以秒为单位）。仅当源对象随对象发送 `Cache-Control` 或 `Expires` 标头时，CloudFront 才使用此设置。有关更多信息，请参阅 [管理内容保留在缓存中的时间长度（过期）](Expiration.md)。

**默认 TTL**  
您希望对象在 CloudFront 缓存中保留的默认时间（以秒为单位），在此时间之后，CloudFront 会向您的源转发另一个请求以确定此对象是否已更新。仅当源*不*随对象发送 `Cache-Control` 或 `Expires` 标头时，CloudFront 才使用此设置的值作为对象的 TTL。有关更多信息，请参阅 [管理内容保留在缓存中的时间长度（过期）](Expiration.md)。

**注意**  
如果**最小 TTL**、**最大 TTL** 和**默认 TTL** 设置都设置为 0，则会禁用 CloudFront 缓存。

## 缓存键设置
<a name="cache-key-understand-cache-policy-settings"></a>

缓存键设置指定 CloudFront 包含在缓存键中的查看器请求的值。这些值可以包括 URL 查询字符串、HTTP 标头和 Cookie。缓存键中包含的值将自动包含在 CloudFront 发送到源的请求（称为*源请求*）中。有关在不影响缓存键的情况下控制源请求的信息，请参阅[使用策略来控制源请求](controlling-origin-requests.md)。

缓存键设置包括：
+ [标头](#cache-policy-headers)
+ [Cookies](#cache-policy-cookies)
+ [查询字符串](#cache-policy-query-strings)
+ [压缩支持](#cache-policy-compressed-objects)

**标头**  
CloudFront 包含在缓存键和源请求中的查看器请求中的 HTTP 标头。对于标头，您可以选择下列设置之一：  
+ **无** – 查看器请求中的 HTTP 标头*不* 会包含在缓存键中，也*不* 会自动包含在源请求中。
+ **Include the following headers**（包含以下标头）– 您可以指定查看器请求中的哪些 HTTP 标头包含在缓存键中，并且会自动包含在源请求中。
在使用 **Include the following headers**（包含以下标头）设置时，可以按 HTTP 标头的名称（而不是值）指定它们。例如，请考虑以下 HTTP 标头：  

```
Accept-Language: en-US,en;q=0.5
```
在此情况下，您可以将标头指定为 `Accept-Language`，而不是指定为 `Accept-Language: en-US,en;q=0.5`。但是，CloudFront 会将完整标头（包括其值）包含在缓存键和源请求中。  
您还可以将 CloudFront 生成的某些标头包含在缓存键中。有关更多信息，请参阅 [添加 CloudFront 请求标头](adding-cloudfront-headers.md)。

**Cookies**  
CloudFront 包含在缓存键和源请求中的查看器请求中的 Cookie。对于 Cookie，您可以选择下列设置之一：  
+ **无** – 查看器请求中的 Cookie *不* 会包含在缓存键中，也*不* 会自动包含在源请求中。
+ **全部** – 查看器请求中的所有 Cookie 都包含在缓存键中，也会自动包含在源请求中。
+ **Include specified cookies**（包含指定 Cookie）– 您可以指定查看器请求中的哪些 Cookie 包含在缓存键中，并且会自动包含在源请求中。
+ **Include all cookies except**（包含全部 Cookie -例外项）– 您可以指定查看器请求中的哪些 Cookie *不* 包含在缓存键中，并且*不*会自动包含在源请求中。所有其他 Cookie（您指定的 Cookie 除外）*都* 包含在缓存键中，并且会自动包含在源请求中。
在使用 **Include specified cookies**（包含指定 Cookie）或 **Include all cookies except**（包含全部 Cookie -例外项）设置时，可以按 Cookie 的名称（而不是值）指定它们。例如，请考虑以下 `Cookie` 标头：  

```
Cookie: session_ID=abcd1234
```
在此情况下，您可以将 Cookie 指定为 `session_ID`，而不是指定为 `session_ID=abcd1234`。但是，CloudFront 会将完整 Cookie（包括其值）包含在缓存键和源请求中。

**查询字符串**  
CloudFront 包含在缓存键和源请求中的查看器请求中的 URL 查询字符串。对于查询字符串，可以选择下列设置之一：  
+ **无** – 查看器请求中的查询字符串*不* 会包含在缓存键中，也*不* 会自动包含在源请求中。
+ **全部** – 查看器请求中的所有查询字符串都包含在缓存键中，并且也会自动包含在源请求中。
+ **Include specified query strings**（包含指定查询字符串）– 您可以指定查看器请求中的哪些查询字符串包含在缓存键中，并且会自动包含在源请求中。
+ **Include all query strings except**（包含全部查询字符串-例外项）– 您可以指定查看器请求中的哪些查询字符串*不* 包含在缓存键中，并且*不* 会自动包含在源请求中。所有其他查询字符串（您指定的查询字符串除外）*都* 包含在缓存键中，并且会自动包含在源请求中。
在使用 **Include specified query strings**（包含指定查询字符串）或 **Include all query strings except**（包含全部查询字符串-例外项）设置时，可以按查询字符串的名称（而不是值）指定它们。例如，请考虑以下 URL 路径：  

```
/content/stories/example-story.html?split-pages=false
```
在此情况下，您可以将查询字符串指定为 `split-pages`，而不是指定为 `split-pages=false`。但是，CloudFront 会将完整的查询字符串（包括其值）包含在缓存键和源请求中。  
对于缓存密钥设置，CloudFront 将标头、查询字符串和 Cookie 的星号字符 (`*`) 视为文本字符串，而不是通配符。

**压缩支持**  
利用这些设置，CloudFront 可以在查看器支持 Gzip 或 Brotli 压缩格式时，请求和缓存以该压缩格式压缩的对象。这些设置还允许 [CloudFront 压缩](ServingCompressedFiles.md)功能发挥作用。查看器通过 `Accept-Encoding` HTTP 标头表示它们支持这些压缩格式。  
Chrome 和 Firefox Web 浏览器仅在使用 HTTPS 发送请求时支持 Brotli 压缩。这些浏览器不支持带 HTTP 请求的 Brotli。
在满足以下任一条件时，启用这些设置：  
+ 当查看器支持 Gzip 压缩对象时，您的源将返回这些对象（请求包含带 `gzip` 的 `Accept-Encoding` HTTP 标头作为值）。在此情况下，使用**启用了 Gzip** 设置（在 CloudFront API、AWS 开发工具包、AWS CLI 或 CloudFormation 中将 `EnableAcceptEncodingGzip` 设置为 `true`）。
+ 当查看器支持 Brotli 压缩对象时，您的源将返回这些对象（请求包含带 `br` 的 `Accept-Encoding` HTTP 标头作为值）。在此情况下，使用**启用了 Brotli** 设置（在 CloudFront API、AWS 开发工具包、AWS CLI 或 CloudFormation 中将 `EnableAcceptEncodingBrotli` 设置为 `true`）。
+ 此缓存策略附加到的缓存行为将通过 [CloudFront 压缩](ServingCompressedFiles.md)进行配置。在此情况下，可以为 Gzip 和/或 Brotli 启用缓存。启用 CloudFront 压缩后，为两种格式启用缓存可帮助降低将数据传输到 Internet 的成本。
如果为其中一种或两种压缩格式启用缓存，则不要在与相同缓存行为关联的[源请求策略](controlling-origin-requests.md)中包含 `Accept-Encoding` 标头。当为这些格式中的任一格式启用缓存时，CloudFront 始终在源请求中包含此标头，因此在源请求策略中包含 `Accept-Encoding` 不起作用。
如果源服务器未返回 Gzip 或 Brotli 压缩对象，或者缓存行为未通 CloudFront 压缩进行配置，则不要为压缩对象启用缓存。如果这样做的话，可能会导致[缓存命中率](cache-hit-ratio.md)下降。  
下面说明了这些设置如何影响 CloudFront 分配。以下所有方案都假定查看器请求包含 `Accept-Encoding` 标头。如果查看器请求不包含 `Accept-Encoding` 标头，则 CloudFront 不会将此标头包含在缓存键和相应的源请求中。    
**在为两种压缩格式支持缓存压缩对象的情况下**  
如果查看器同时支持 Gzip 和 Brotli，即，如果 `gzip` 和 `br` 值都在查看器请求中的 `Accept-Encoding` 标头中，CloudFront 将执行以下操作：  
+ 将标头标准化为 `Accept-Encoding: br,gzip` 并将标准化的标头包含在缓存键中。缓存键不包含查看器发送的 `Accept-Encoding` 标头中的其他值。
+ 如果边缘站点在缓存中具有与请求匹配的 Brotli 或 Gzip 压缩对象，并且未过期，则边缘站点会将此对象返回给查看器。
+ 如果边缘站点在缓存中没有与请求匹配的 Brotli 或 Gzip 压缩对象，并且未过期，则 CloudFront 会将标准化的标头（`Accept-Encoding: br,gzip`）包含在相应的源请求中。源请求不包含查看器发送的 `Accept-Encoding` 标头中的其他值。
如果查看器支持一种压缩格式，而不支持另一种压缩格式例如，如果 `gzip` 是查看器请求中 `Accept-Encoding` 标头中的值，而 `br` 不是，则 CloudFront 将执行以下操作：  
+ 将标头标准化为 `Accept-Encoding: gzip` 并将标准化的标头包含在缓存键中。缓存键不包含查看器发送的 `Accept-Encoding` 标头中的其他值。
+ 如果边缘站点在缓存中具有与请求匹配的 Gzip 压缩对象，并且未过期，则边缘站点会将此对象返回给查看器。
+ 如果边缘站点在缓存中没有与请求匹配的 Gzip 压缩对象，并且未过期，则 CloudFront 会将标准化的标头（`Accept-Encoding: gzip`）包含在相应的源请求中。源请求不包含查看器发送的 `Accept-Encoding` 标头中的其他值。
要了解当查看器支持 Brotli 而非 Gzip 时，CloudFront 将执行的操作，请在前面示例中将两种压缩格式相互替换。  
如果查看器不支持 Brotli 或 Gzip，即，查看器请求中的 `Accept-Encoding` 标头不包含 `br` 或 `gzip` 作为值，则 CloudFront：  
+ 不会将 `Accept-Encoding` 标头包含在缓存键中。
+ 将 `Accept-Encoding: identity` 包含在相应的源请求中。源请求不包含查看器发送的 `Accept-Encoding` 标头中的其他值。  
**在为一种压缩格式（而非另一种压缩格式）支持缓存压缩对象的情况下**  
例如，如果查看器支持已启用缓存的格式，例如，为 Gzip 启用缓存压缩对象并且查看器支持 Gzip（`gzip` 是查看器请求中 `Accept-Encoding` 标头中的值之一），CloudFront 将执行以下操作：  
+ 将标头标准化为 `Accept-Encoding: gzip` 并将标准化的标头包含在缓存键中。
+ 如果边缘站点在缓存中具有与请求匹配的 Gzip 压缩对象，并且未过期，则边缘站点会将此对象返回给查看器。
+ 如果边缘站点在缓存中没有与请求匹配的 Gzip 压缩对象，并且未过期，则 CloudFront 会将标准化的标头（`Accept-Encoding: gzip`）包含在相应的源请求中。源请求不包含查看器发送的 `Accept-Encoding` 标头中的其他值。
当查看器同时支持 Gzip 和 Brotli（查看器请求中的 `Accept-Encoding` 标头包含 `gzip` *和* `br` 作为值）时，此行为是相同的，因为在这种情况下，不支持为 Brotli 缓存压缩对象。  
要了解当为 Brotli 而非 Gzip 支持缓存压缩对象时，CloudFront 将执行的操作，请在前面示例中将两种压缩格式相互替换。  
如果查看器不支持已启用缓存的压缩格式（查看器请求中的 `Accept-Encoding` 标头不包含该格式的值），则 CloudFront：  
+ 不会将 `Accept-Encoding` 标头包含在缓存键中。
+ 将 `Accept-Encoding: identity` 包含在相应的源请求中。源请求不包含查看器发送的 `Accept-Encoding` 标头中的其他值。  
**在不支持为两种压缩格式缓存压缩对象的情况下**  
在不支持为两种压缩格式缓存压缩对象时，CloudFront 会像处理查看器请求中的任何其他 HTTP 标头一样处理 `Accept-Encoding` 标头。默认情况下，它不包括在缓存键中，也不包括在源请求中。与任何其他 HTTP 标头一样，可以将此标头包含在缓存策略或源请求策略中的标头列表中。