

# 提供压缩文件
<a name="ServingCompressedFiles"></a>

在压缩请求的对象时，由于对象更小（在某些情况下，大小不到原件的四分之一），因此下载速度可能更快。更快的下载可能导致向查看器更快地呈现网页，尤其是对于 JavaScript 和 CSS 文件。此外，CloudFront 数据传输的费用基于提供的数据总量。提供压缩的对象可能比提供未压缩的对象更便宜。

**Topics**
+ [

## 配置 CloudFront 来压缩对象
](#compressed-content-cloudfront-configuring)
+ [

## CloudFront 压缩的工作原理
](#compressed-content-cloudfront-how-it-works)
+ [

## 压缩的条件
](#compressed-content-cloudfront-notes)
+ [

## CloudFront 压缩的文件类型
](#compressed-content-cloudfront-file-types)
+ [

## `ETag` 标头转换
](#compressed-content-cloudfront-etag-header)

## 配置 CloudFront 来压缩对象
<a name="compressed-content-cloudfront-configuring"></a>

要将 CloudFront 配置为压缩对象，请更新您要提供压缩对象的缓存行为。

**将 CloudFront 配置为压缩对象（控制台）**

1. 登录 [CloudFront 控制台](https://console.aws.amazon.com/cloudfront/v4/home)。

1. 选择您的分配，然后选择要编辑的**行为**。

1. 对于**自动压缩对象**设置，选择**是**。

1. 使用[缓存策略](controlling-the-cache-key.md)来指定缓存设置，并同时启用 **Gzip** 和 **Brotli** 压缩格式。

**备注**  
您必须使用[缓存策略](controlling-the-cache-key.md)，才能使用 Brotli 压缩。Brotli 不支持旧版缓存设置。
要使用 [CloudFormation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-cachebehavior.html) 或 [CloudFront](https://docs.aws.amazon.com/cloudfront/latest/APIReference/Welcome.html) API 启用压缩，请将 `Compress`、`EnableAcceptEncodingGzip`、`EnableAcceptEncodingBrotli` 参数设置为 `true`。

要了解 CloudFront 如何压缩对象，请参阅以下部分。

## CloudFront 压缩的工作原理
<a name="compressed-content-cloudfront-how-it-works"></a>

1. 查看器请求对象。查看器在请求中包含 `Accept-Encoding` HTTP 标头，标头值包含 `gzip`、`br` 或同时包含二者。这表示查看器支持压缩对象。当查看器同时支持 Gzip 和 Brotli 时，CloudFront 使用 Brotli。
**注意**  
Chrome 和 Firefox Web 浏览器仅在使用 HTTPS 发送请求时才支持 Brotli 压缩。它们不支持对 HTTP 请求使用 Brotli。

1. 在边缘站点，CloudFront 将检查缓存中有无所请求对象的压缩副本。

1. 根据压缩对象是否在缓存中，CloudFront 执行以下操作之一：
   + 如果压缩的对象已在缓存中，则 CloudFront 将该对象发送到查看器并跳过剩余步骤。
   + 如果压缩的对象不在缓存中，则 CloudFront 将请求转发到源。
**注意**  
如果缓存中已有对象的未压缩副本，CloudFront 可能会将其发送到查看器，而不将请求转发到源。例如，当 CloudFront [先前跳过了压缩](#compression-skipped)时，可能会发生这种情况。发生这种情况时，CloudFront 会缓存未压缩的对象并继续处理该对象，直到对象过期、移出或失效。

1. 如果源返回了压缩对象（通过 HTTP 响应中的 `Content-Encoding` 标头指示），CloudFront 将该压缩对象发送给查看器，将其添加到缓存中，并跳过剩余步骤。CloudFront 不会再次压缩对象。

1. 如果源将未压缩的对象返回到 CloudFront（HTTP 响应中无 `Content-Encoding` 标头），则 CloudFront 将确定对象是否可压缩。有关更多信息，请参阅 [压缩的条件](#compressed-content-cloudfront-notes)。

1. 如果对象可压缩，则 CloudFront 将压缩该对象，然后将其发送到查看器，之后将其添加到缓存中。

1. 如果有对同一对象的后续查看器请求，CloudFront 将返回第一个缓存版本。例如，如果查看器请求一个使用 Gzip 压缩的特定缓存对象，而查看器*接受* Gzip 格式，则对同一对象的后续请求将始终返回 Gzip 版本，即使查看器同时接受 Brotli 和 Gzip 也是如此。

某些自定义源也可以压缩对象。源也许能够压缩 CloudFront 未压缩的对象。有关更多信息，请参阅 [CloudFront 压缩的文件类型](#compressed-content-cloudfront-file-types)。

## 压缩的条件
<a name="compressed-content-cloudfront-notes"></a>

以下列表提供了有关 CloudFront 不压缩对象的场景的更多信息。

**请求使用 HTTP 1.0**  
如果对 CloudFront 的请求使用 HTTP 1.0，则 CloudFront 将移除 `Accept-Encoding` 标头，并且不会压缩响应中的对象。

**`Accept-Encoding` 请求标头**  
如果查看器请求中缺失 `Accept-Encoding` 标头，或者如果该标头未包含 `gzip` 或 `br` 作为值，则 CloudFront 不会压缩响应中的对象。如果 `Accept-Encoding` 标头包含其他值（例如 `deflate`），则 CloudFront 会先删除这些值，然后再将请求转发到源。  
当 CloudFront [配置为压缩对象](#compressed-content-cloudfront-configuring)时，它自动在缓存键中和源请求中包含 `Accept-Encoding` 标头。

**当您将 CloudFront 配置为压缩对象时，内容已被缓存**  
CloudFront 在从源获取对象时压缩对象。当您将 CloudFront 配置为压缩对象时，CloudFront 不会压缩已在边缘站点中缓存的对象。此外，如果边缘站点中的缓存对象过期，并且 CloudFront 将针对该对象的另一个请求转发到源，则当源返回 HTTP 状态代码 304 时，CloudFront 不会压缩该对象。这意味着边缘站点已有最新版本的对象。如果您希望 CloudFront 压缩已在边缘站点中缓存的对象，需要使这些对象失效。有关更多信息，请参阅[使文件失效以删除内容](Invalidation.md)。

**源已配置为压缩对象**  
如果将 CloudFront 配置为压缩对象，并且源也压缩对象，则源应包含 `Content-Encoding` 标头。此标头向 CloudFront 表明已压缩该对象。如果来自源的响应包含 `Content-Encoding` 标头，则无论标头的值如何，CloudFront 都不会压缩对象。CloudFront 将响应发送给查看器，并在边缘站点缓存对象。

**CloudFront 压缩的文件类型**  
有关完整列表，请参阅[CloudFront 压缩的文件类型](#compressed-content-cloudfront-file-types)。

**CloudFront 压缩的对象大小**  
CloudFront 压缩大小介于 1000 字节和 10000000 字节之间的对象。

**`Content-Length` 标头**  
源必须在响应中包含 `Content-Length` 标头，CloudFront 使用它来确定对象大小是否在 CloudFront 压缩的范围内。如果 `Content-Length` 标头缺失、包含无效值或包含超出 CloudFront 可压缩的大小范围的值，则 CloudFront 不会压缩该对象。有关 CloudFront 如何处理可能超过大小范围的大型对象的更多信息，请参阅 [CloudFront 如何处理对象的部分请求 (Range GET)。](RangeGETs.md)。

**响应的 HTTP 状态代码**  
CloudFront 仅在响应的 HTTP 状态代码为 `200`、`403` 或 `404` 时压缩对象。

**响应没有正文**  
当来自源的 HTTP 响应没有正文时，CloudFront 没有任何可以压缩的内容。

**`ETag` 标头**  
CloudFront 有时会在压缩对象时修改 HTTP 响应中的 `ETag` 标头。有关更多信息，请参阅 [`ETag` 标头转换](#compressed-content-cloudfront-etag-header)。

**CloudFront 跳过压缩**  
CloudFront 将尽最大努力压缩对象。在极少数情况下，当 CloudFront 遇到高流量负载时，CloudFront 会跳过压缩对象的过程。CloudFront 根据包括主机容量在内的各种因素做出此决定。如果 CloudFront 跳过对象的压缩，它会缓存未压缩的对象，并在该对象过期、被移出或失效之前继续将其提供给查看器。

## CloudFront 压缩的文件类型
<a name="compressed-content-cloudfront-file-types"></a>

如果您将 CloudFront 配置为压缩对象，则 CloudFront 仅压缩 `Content-Type` 响应标头中具有以下值之一的对象：
+ `application/dash+xml`
+ `application/eot`
+ `application/font`
+ `application/font-sfnt`
+ `application/javascript`
+ `application/json`
+ `application/opentype`
+ `application/otf`
+ `application/pdf`
+ `application/pkcs7-mime`
+ `application/protobuf`
+ `application/rss+xml`
+ `application/truetype`
+ `application/ttf`
+ `application/vnd.apple.mpegurl`
+ `application/vnd.mapbox-vector-tile`
+ `application/vnd.ms-fontobject`
+ `application/wasm`
+ `application/xhtml+xml`
+ `application/xml`
+ `application/x-font-opentype`
+ `application/x-font-truetype`
+ `application/x-font-ttf`
+ `application/x-httpd-cgi`
+ `application/x-javascript`
+ `application/x-mpegurl`
+ `application/x-opentype`
+ `application/x-otf`
+ `application/x-perl`
+ `application/x-ttf`
+ `font/eot`
+ `font/opentype`
+ `font/otf`
+ `font/ttf`
+ `image/svg+xml`
+ `text/css`
+ `text/csv`
+ `text/html`
+ `text/javascript`
+ `text/js`
+ `text/plain`
+ `text/richtext`
+ `text/tab-separated-values`
+ `text/xml`
+ `text/x-component`
+ `text/x-java-source`
+ `text/x-script`
+ `vnd.apple.mpegurl`

## `ETag` 标头转换
<a name="compressed-content-cloudfront-etag-header"></a>

当来自源的未压缩对象包含有效的强 `ETag` HTTP 标头并且 CloudFront 压缩该对象时，CloudFront 还会将强 `ETag` 标头值转换为弱 `ETag`，并将弱 `ETag` 值返回到查看器。查看器可以存储弱 `ETag` 值并使用它来发送带 `If-None-Match` HTTP 标头的条件请求。这允许查看器、CloudFront 和源将对象的压缩版本和未压缩版本视为语义等效，从而减少不必要的数据传输。

有效的强 `ETag` 标头值以双引号字符（`"`）开头和结尾。为了将强 `ETag` 值转换为弱值，CloudFront 会将字符 `W/` 添加到强 `ETag` 值的开头。

当来自源的对象包含弱 `ETag` 标头值（以字符 `W/` 开头的值）时，CloudFront 不会修改此值，并会在从源接收此值后将它返回到查看器。

当来自源的对象包含无效的 `ETag` 标头值（该值不以 `"` 或 `W/` 开头）时，CloudFront 会删除 `ETag` 标头，并将对象返回到查看器而不带 `ETag` 响应标头。

有关更多信息，请参阅 MDN Web 文档中的以下页面：
+ [指令](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag#Directives) （`ETag` HTTP 标头）
+ [弱验证](https://developer.mozilla.org/en-US/docs/Web/HTTP/Conditional_requests#Weak_validation)（HTTP 条件请求）
+ [If-None-Match HTTP 标头](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-None-Match)