

# 根据查询字符串参数缓存内容
<a name="QueryStringParameters"></a>

一些 Web 应用程序使用查询字符串将信息发送到源。查询字符串是 Web 请求的一部分，显示在 `?` 字符之后；该字符串可以包含一个或多个使用 `&` 字符分隔的参数。在以下示例中，查询字符串包括两个参数 *color=red* 和 *size=large*：

`https://d111111abcdef8.cloudfront.net/images/image.jpg?color=red&size=large`

对于分配，您可选择是否希望 CloudFront 将查询字符串转发到源，以及是基于所有参数还是基于选定参数缓存内容。为什么说这可能很有用？ 考虑以下 示例。

假设您的网站提供五种语言。网站的全部五个版本的目录结构和文件名均相同。用户查看网站时，转发到 CloudFront 的请求包括语言查询字符串参数，该参数基于用户选择的语言。您可以将 CloudFront 配置为将查询字符串转发到源，并基于语言参数进行缓存。如果您将 Web 服务器配置为返回指定页面的与所选语言对应的版本，CloudFront 将基于语言查询字符串参数的值分别缓存各个语言版本。

在此示例中，如果您网站的主页为 `main.html`，则以下五个请求将导致 CloudFront 缓存 `main.html` 五次，为语言查询字符串参数的每个值缓存一次：
+ `https://d111111abcdef8.cloudfront.net/main.html?language=de`
+ `https://d111111abcdef8.cloudfront.net/main.html?language=en`
+ `https://d111111abcdef8.cloudfront.net/main.html?language=es`
+ `https://d111111abcdef8.cloudfront.net/main.html?language=fr`
+ `https://d111111abcdef8.cloudfront.net/main.html?language=jp`

请注意以下几点：
+ 一些 HTTP 服务器不处理查询字符串参数，因此，不基于参数值返回对象的不同版本。对于这些源，如果将 CloudFront 配置为将查询字符串参数转发到源，CloudFront 仍根据参数值进行缓存，即使源针对每个参数值向 CloudFront 返回完全相同的对象版本。
+ 要使查询字符串参数与语言结合使用（如上述示例中所述），您必须使用 `&` 字符作为查询字符串参数之间的分隔符。如果您使用不同的分隔符，则可能获得意外结果，具体取决于您为 CloudFront 指定的用作缓存基础的参数以及这些参数在查询字符串中的显示顺序。

  以下示例说明在您使用其他分隔符并将 CloudFront 配置为仅根据 `color` 参数进行缓存时发生的情况：
  + 在以下请求中，CloudFront 根据 `color` 参数值缓存您的内容，但 CloudFront 将值解释为 *red;size=large*：

    `https://d111111abcdef8.cloudfront.net/images/image.jpg?color=red;size=large`
  + 在以下请求中，CloudFront 缓存内容，但不根据查询字符串参数进行缓存。这是因为您将 CloudFront 配置成了基于 `color` 参数进行缓存，但 CloudFront 将以下字符串解释为仅包含 `size` 参数且其值为 *large;color=red*：

    `https://d111111abcdef8.cloudfront.net/images/image.jpg?size=large;color=red`

您可以将 CloudFront 配置为执行下列操作之一：
+ 完全不将查询字符串转发到源。如果您不转发查询字符串，CloudFront 不基于查询字符串参数进行缓存。
+ 将查询字符串转发到源，并基于查询字符串中的所有参数进行缓存。
+ 将查询字符串转发到源，并基于查询字符串中的指定参数进行缓存。

有关更多信息，请参阅 [优化缓存](#query-string-parameters-optimizing-caching)。

**Topics**
+ [

## 针对查询字符串转发和缓存的控制台和 API 设置
](#query-string-parameters-console)
+ [

## 优化缓存
](#query-string-parameters-optimizing-caching)
+ [

## 查询字符串参数和 CloudFront 标准日志（访问日志）
](#query-string-parameters-access-logs)

## 针对查询字符串转发和缓存的控制台和 API 设置
<a name="query-string-parameters-console"></a>

当您在 CloudFront 控制台中创建分配时，CloudFront 会根据源类型为您配置查询字符串转发和缓存。（可选）您可以手动编辑这些设置。有关更多信息，请参阅[所有分配设置参考](distribution-web-values-specify.md)中的以下设置：
+ [查询字符串转发和缓存](DownloadDistValuesCacheBehavior.md#DownloadDistValuesQueryString)
+ [查询字符串允许列表](DownloadDistValuesCacheBehavior.md#DownloadDistValuesQueryStringAllowlist)

要使用 CloudFront API 配置查询字符串转发和缓存，请参阅《Amazon CloudFront API 参考》**中的 [CachePolicy](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_CachePolicy.html) 和 [OriginRequestPolicy](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_OriginRequestPolicy.html)。

## 优化缓存
<a name="query-string-parameters-optimizing-caching"></a>

在将 CloudFront 配置为根据查询字符串参数进行缓存时，可以执行以下步骤来减少 CloudFront 转发到源的请求数。当 CloudFront 边缘站点为对象提供服务时，您可以减少源服务器上的负载并减少延迟，因为从更接近用户的位置为对象提供了服务。

**仅基于源为其返回不同版本的对象的参数进行缓存**  
对于您的 Web 应用程序转发到 CloudFront 的每个查询字符串参数，CloudFront 针对每个参数值将请求转发到您的源，并为每个参数值缓存对象的单独版本。即使不论参数值如何，源始终返回相同的对象时，也是如此。对于多个参数，请求数和对象数相乘。  
建议您将 CloudFront 配置为仅基于源会返回不同版本的查询字符串参数进行缓存，并建议您谨慎考虑基于各参数进行缓存的优点。例如，假设您有一个零售网站。您有六种不同颜色的夹克衫的照片，夹克衫有 10 种不同的尺寸。您的夹克衫图片会显示不同颜色，但没有不同尺寸。要优化缓存，您应将 CloudFront 配置为仅基于颜色参数进行缓存，而非尺寸参数。这增加了 CloudFront 可从缓存满足请求的可能性，这提高了性能并降低了源的负载。

**始终按相同的顺序列出参数**  
查询字符串中参数的顺序很重要。在以下示例中，查询字符串相同，但参数的顺序不同。这将导致 CloudFront 将两个针对 image.jpg 的单独请求转发到源，并缓存对象的两个单独版本：  
+ `https://d111111abcdef8.cloudfront.net/images/image.jpg?color=red&size=large`
+ `https://d111111abcdef8.cloudfront.net/images/image.jpg?size=large&color=red`
建议您始终按相同的顺序列出参数名称，例如字母顺序。

**始终为参数名称和值使用相同的大小写**  
CloudFront 在基于查询字符串参数进行缓存时，会考虑参数名称和值的大小写情况。在以下示例中，查询字符串相同，但参数名称和值的大小写不同。这将导致 CloudFront 将四个针对 image.jpg 的单独请求转发到源，并缓存对象的四个单独版本：  
+ `https://d111111abcdef8.cloudfront.net/images/image.jpg?color=red`
+ `https://d111111abcdef8.cloudfront.net/images/image.jpg?color=Red`
+ `https://d111111abcdef8.cloudfront.net/images/image.jpg?Color=red`
+ `https://d111111abcdef8.cloudfront.net/images/image.jpg?Color=Red`
建议您为参数名称和值使用一致的大小写，例如全小写。

**不要使用与签名 URL 冲突的参数名称**  
如果您使用签名 URL 限制访问您的内容（如果您添加了可信签署人到您的分配），CloudFront 在转发 URL 剩余部分到您的源之前将删除以下查询字符串参数：  
+ `Expires`
+ `Key-Pair-Id`
+ `Policy`
+ `Signature`
如果您使用已签名 URL 并且希望将 CloudFront 配置为将查询字符串转发到源，您自己的查询字符串参数不能命名为 `Expires`、`Key-Pair-Id`、`Policy` 或 `Signature`。

## 查询字符串参数和 CloudFront 标准日志（访问日志）
<a name="query-string-parameters-access-logs"></a>

如果您启用日志记录，则 CloudFront 会记录完整的 URL，包括查询字符串参数。无论您是否将 CloudFront 配置为将查询字符串转发到源都是如此。有关 CloudFront 日志记录的更多信息，请参阅[访问日志（标准日志）](AccessLogs.md)。