

# CloudFront 如何处理对象的部分请求 (Range GET)。
<a name="RangeGETs"></a>

对于大型对象，查看器（Web 浏览器或客户端）可能做出多个 `GET` 请求并使用 `Range` 请求标头以较小的段下载对象。字节范围的这些请求，有时也被称为 `Range GET` 请求，提高了部分下载的效率和恢复部分失败的传输。

当 CloudFront 接收 `Range GET` 请求时，其检查接收请求的边缘站点中的缓存。如果边缘站点中的缓存已经包含整个对象或请求的对象段，CloudFront 会立即从缓存提供所请求的范围。

如果缓存不包含所请求的范围，CloudFront 会将请求转发到源。（要优化性能，CloudFront 可请求比客户端在 `Range GET` 中请求的范围更大的范围。） 接下来会发生的操作取决于源是否支持 `Range GET` 请求：
+ **源支持 `Range GET` 请求时** – 返回所请求的范围。CloudFront 提供被请求的范围，而且还对其进行缓存以用于将来的请求。（与许多 HTTP 服务器一样，Amazon S3 支持 `Range GET` 请求。）
+ **源不支持 `Range GET` 请求时** – 返回整个对象。CloudFront 通过发送整个对象来满足当前请求，同时缓存它以用于将来的请求。在 CloudFront 在边缘缓存中缓存整个对象后，它通过提供被请求的范围响应新的 `Range GET` 请求。

无论是哪种情况，CloudFront 都会在第一个字节到达后从源开始向最终用户提供所请求的范围或对象。

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

CloudFront 一般遵照 `Range` 标头的 RFC 规范。但是，如果您的 `Range` 标头不遵守以下要求，CloudFront 将返回 HTTP 状态码 `200` 与完整的对象，而不是状态码 `206` 与指定的范围：
+ 范围必须列按升序排列。例如，`100-200,300-400` 是有效的，`300-400,100-200` 是无效的。
+ 范围不能重叠。例如，`100-200,150-250` 是无效的。
+ 所有范围的规范必须有效。例如，您不能指定负值作为范围的一部分。

有关 `Range` 请求标头的更多信息，请参阅 RFC 7233 中的[范围请求](https://httpwg.org/specs/rfc7233.html#range.requests)，或者 MDN Web Docs 中的[范围](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Range)。

## 使用范围请求缓存大型对象
<a name="cache-large-objects-with-range-requests"></a>

启用缓存后，CloudFront 不会检索或缓存大于 50 GB 的对象。如果源表示对象大于此大小（在 `Content-Length` 响应标头中），CloudFront 将关闭与源的连接并向查看器返回一条错误。（禁用缓存后，CloudFront 可以从源检索大于此大小的对象，然后将其传递给查看器。但是，CloudFront 不会缓存该对象。）

但借助范围请求，您可以使用 CloudFront 缓存超过[最大可缓存文件大小](cloudfront-limits.md#limits-web-distributions)的对象。

**Example 示例**  

1.  假设某个源中具有一个 100 GB 的对象。启用缓存后，CloudFront 不会检索或缓存这样大的对象。但查看器可以发送多个范围请求以分段检索此对象，每个段小于 50 GB。

1. 查看器可以发送一个带有 `Range: bytes=0-21474836480` 标头的请求检索第一段，发送另一个带有 `Range: bytes=21474836481-42949672960` 的请求以检索下一段，依此类推，从而按 20 GB 的段请求该对象。

1. 查看器收到所有段后，可以将这些段组合起来构建原始的 100GB 对象。

1. 在此例中，CloudFront 会缓存该对象的所有 20GB 段，并且可以响应对缓存中相同段的后续请求。

对于面向压缩对象的范围请求，字节范围请求基于压缩的大小，而不是对象的原始大小。有关压缩文件的更多信息，请参阅[提供压缩文件](ServingCompressedFiles.md)。