

# 通用存储桶的虚拟托管
<a name="VirtualHosting"></a>

虚拟托管是指从单个 Web 服务器为多个网站提供服务的做法。区分 Amazon S3 REST API 请求中的站点的一种方法是通过使用请求-URI 的显式主机名，而不只是 URI 的路径名称部分。普通的 Amazon S3 REST 请求使用“请求-URI”路径的第一个斜杠分隔部分指定存储桶。相反，您可以通过使用 HTTP `Host` 标头，在 REST API 调用中使用 Amazon S3 虚拟托管对通用存储桶进行寻址。事实上，Amazon S3 会将 `Host` 解释为可在 `https://bucket-name.s3.region-code.amazonaws.com` 上自动访问大多数存储桶（对于有限类型的请求）。有关 Amazon S3 区域和端点的完整列表，请参阅《Amazon Web Services 一般参考》**中的 [Amazon S3 端点和限额](https://docs.aws.amazon.com/general/latest/gr/s3.html)。

虚拟托管还有其他好处。通过使用注册域名来命名您的存储桶，并将该名称设为 Amazon S3 的 DNS 别名，您可以完全自定义 Amazon S3 资源的 URL，例如：`http://my.bucket-name.com/`。您还可以发布到存储桶的虚拟服务器的“根目录”。此功能很重要，因为许多现有应用程序在此标准位置搜索文件。例如，`favicon.ico`、`robots.txt` 和 `crossdomain.xml` 都应可在根目录下找到。

**重要**  
当通过 SSL 使用虚拟托管类型通用存储桶时，SSL 通配符证书仅匹配不包含句点 (`.`) 的存储桶。要解决此问题，请使用 HTTP 或编写自己的证书验证逻辑。有关更多信息，请参阅 *AWS 新闻博客* 上的 [Amazon S3 路径弃用计划](https://aws.amazon.com/blogs/aws/amazon-s3-path-deprecation-plan-the-rest-of-the-story/)。

**Topics**
+ [路径类型请求](#path-style-access)
+ [虚拟托管类型请求](#virtual-hosted-style-access)
+ [HTTP `Host` 标头桶规范](#VirtualHostingSpecifyBucket)
+ [示例](#VirtualHostingExamples)
+ [使用 CNAME 记录自定义 Amazon S3 URL](#VirtualHostingCustomURLs)
+ [如何将主机名与 Amazon S3 桶关联](#VirtualHostingCustomURLsHowTo)
+ [限制](#VirtualHostingLimitations)
+ [向后兼容性](#VirtualHostingBackwardsCompatibility)

## 路径类型请求
<a name="path-style-access"></a>

目前，Amazon S3 在所有 AWS 区域中同时支持虚拟托管类型和路径类型 URL 访问。但是，路径类型 URL 将来会停用。有关更多信息，请参阅下面的**重要**提示。

在 Amazon S3 中，路径类型 URL 使用以下格式：

```
https://s3.region-code.amazonaws.com/bucket-name/key-name
```

例如，如果您在美国西部（俄勒冈）区域中创建一个名为 `amzn-s3-demo-bucket1` 的存储桶，并希望访问该存储桶中的 `puppy.jpg` 对象，则可使用以下路径类型 URL：

```
https://s3.us-west-2.amazonaws.com/amzn-s3-demo-bucket1/puppy.jpg
```

**重要**  
更新（2020 年 9 月 23 日）– 为确保客户有时间转换到虚拟托管类型 URL，我们决定推迟弃用路径类型 URL。有关更多信息，请参阅 *AWS 新闻博客*中的 [Amazon S3 路径弃用计划 – 案例的其余部分](https://aws.amazon.com/blogs/aws/amazon-s3-path-deprecation-plan-the-rest-of-the-story/)。

**警告**  
托管将通过 Web 浏览器访问的网站内容时，请避免使用路径样式 URL，因为这可能会干扰浏览器的同源安全模型。要托管网站内容，我们建议您使用 S3 网站端点或 CloudFront 分配。有关更多信息，请参阅[网站端点](WebsiteEndpoints.md)和《AWS 透视指导模式》**中的[将基于 React 的单页应用程序部署到 Amazon S3 和 CloudFront](https://docs.aws.amazon.com/prescriptive-guidance/latest/patterns/deploy-a-react-based-single-page-application-to-amazon-s3-and-cloudfront.html)。

## 虚拟托管类型请求
<a name="virtual-hosted-style-access"></a>

在虚拟托管类型 URI 中，存储桶名称是 URL 中域名的一部分。

Amazon S3 虚拟托管类型 URL 使用以下格式：

```
https://bucket-name.s3.region-code.amazonaws.com/key-name
```

在此示例中，`amzn-s3-demo-bucket1` 为存储桶名称，美国西部（俄勒冈）为区域，`puppy.png` 为密钥名称：

```
https://amzn-s3-demo-bucket1.s3.us-west-2.amazonaws.com/puppy.png
```

## HTTP `Host` 标头桶规范
<a name="VirtualHostingSpecifyBucket"></a>

只要您的 `GET` 请求不使用 SSL 终端节点，您就可以通过使用 HTTP `Host` 标头为请求指定存储桶。REST 请求中的 `Host` 标头解释如下：
+ 如果 `Host` 标头被省略，或其值为 `s3.region-code.amazonaws.com`，则该请求的存储桶将是请求-URI 的第一个斜杠分隔的部分，而且该请求的键将是请求-URI 的其余部分。这是常用方法，如本部分第一个和第二个示例所示。省略 `Host` 标头仅对于 HTTP 1.0 请求有效。
+ 否则，如果 `Host` 标头的值以 `.s3.region-code.amazonaws.com` 结尾，则存储桶名称是 `Host` 标头值中从开头到 `.s3.region-code.amazonaws.com` 的部分。该请求的键值为“Request-URI”。此解释将存储桶公开为 `.s3.region-code.amazonaws.com` 的子域，如本部分第三和第四个示例所示。
+ 否则，请求的存储桶是 `Host` 标头的小写值，请求的键值是“Request-URI”。如果注册的 DNS 名称与桶名称相同，并且已将该名称配置为 Amazon S3 的规范名称 (CNAME) 别名，则此解释很有用。注册域名和配置 CNAME DNS 记录的过程不在本指南的范围内，但本节中的最后一个示例展示了结果。

## 示例
<a name="VirtualHostingExamples"></a>

本节提供示例 URL 和请求。

**Example – 路径类型 URL 和请求**  
此示例使用以下内容：  
+ 存储桶名称 – `example.com`
+ 区域 – 美国东部（弗吉尼亚北部） 
+ 键名 – `homepage.html`
URL 如下：  

```
1. http://s3.us-east-1.amazonaws.com/example.com/homepage.html
```
请求如下：  

```
1. GET /example.com/homepage.html HTTP/1.1
2. Host: s3.us-east-1.amazonaws.com
```
具有 HTTP 1.0 且省略 `Host` 标头的请求如下：  

```
1. GET /example.com/homepage.html HTTP/1.0
```

有关 DNS 兼容名称的信息，请参阅[限制](#VirtualHostingLimitations)。有关密钥的更多信息，请参阅[密钥](Welcome.md#BasicsKeys)。

**Example – 虚拟托管类型 URL 和请求**  
此示例使用以下内容：  
+ **桶名称** ‐ `amzn-s3-demo-bucket1` 
+ **区域** – 欧洲（爱尔兰） 
+ **键名** ‐ `homepage.html`
URL 如下：  

```
1. http://amzn-s3-demo-bucket1.s3.eu-west-1.amazonaws.com/homepage.html
```
请求如下：  

```
1. GET /homepage.html HTTP/1.1
2. Host: amzn-s3-demo-bucket1.s3.eu-west-1.amazonaws.com
```

**Example – CNAME 别名方法**  
要使用此方法，您必须将 DNS 名称配置为 `bucket-name.s3.us-east-1.amazonaws.com` 的 CNAME 别名。有关更多信息，请参阅 [使用 CNAME 记录自定义 Amazon S3 URL](#VirtualHostingCustomURLs)。  
此示例使用以下内容：  
+ 存储桶名称 – `example.com` 
+ **键名称** ‐ `homepage.html`
URL 如下：  

```
1. http://www.example.com/homepage.html
```
示例如下：  

```
1. GET /homepage.html HTTP/1.1
2. Host: www.example.com
```

## 使用 CNAME 记录自定义 Amazon S3 URL
<a name="VirtualHostingCustomURLs"></a>

根据您的需要，您可能不希望 `s3.region-code.amazonaws.com` 显示在网站或服务中。例如，如果您在 Amazon S3 上托管网站映像，您可能会首选 `http://images.example.com/`，而不是 `http://images.example.com.s3.us-east-1.amazonaws.com/`。具有 DNS 兼容名称的任何存储桶都可按以下方式引用：` http://BucketName.s3.Region.amazonaws.com/[Filename]`，例如 `http://images.example.com.s3.us-east-1.amazonaws.com/mydog.jpg`。通过使用 CNAME，您可以将 `images.example.com` 映射到 Amazon S3 主机名，使上面的 URL 变成 `http://images.example.com/mydog.jpg`。

存储桶名称必须与 CNAME 相同。例如，如果您创建一个 CNAME 以将 `images.example.com` 映射到 `images.example.com.s3.us-east-1.amazonaws.com`，则 `http://images.example.com/filename` 和 `http://images.example.com.s3.us-east-1.amazonaws.com/filename` 两者将相同。

CNAME DNS 记录应将您的域名别名设置为适当的虚拟托管类型主机名。例如，如果存储桶名称和域名是 `images.example.com` 而存储桶位于美国东部（弗吉尼亚北部）区域中，则 CNAME 记录的别名应为 `images.example.com.s3.us-east-1.amazonaws.com`。

```
1. images.example.com CNAME 			images.example.com.s3.us-east-1.amazonaws.com.
```

Amazon S3 使用主机名来确定存储桶名称。所以 CNAME 和存储桶名称必须相同。例如，假定您配置了 `www.example.com` 作为 `www.example.com.s3.us-east-1.amazonaws.com` 的别名记录。当您访问`http://www.example.com`时，Amazon S3 会收到如以下所示的请求：

**Example**  

```
1. GET / HTTP/1.1
2. Host: www.example.com
3. Date: date
4. Authorization: signatureValue
```

Amazon S3 仅查看原始主机名 `www.example.com` 且不知道用于解决请求的 CNAME 映射。

您可以在 CNAME 别名中使用任何 Amazon S3 端点。例如，`s3.ap-southeast-1.amazonaws.com` 可用于 CNAME 别名中。有关端点的更多信息，请参阅《Amazon S3 API Reference》**中的 [Request endpoints](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTAPI.html)。要使用自定义域创建静态网站，请参阅[教程：使用注册到 Route 53 的自定义域配置静态网站](website-hosting-custom-domain-walkthrough.md)。

**重要**  
将自定义 URL 与 CNAME 结合使用时，您需要确保对于您配置的任何 CNAME 或别名记录都存在匹配的桶。例如，如果您为 `www.example.com` 和 `login.example.com` 创建 DNS 条目以使用 S3 发布 Web 内容，将需要同时创建两个桶 `www.example.com` 和 `login.example.com`。  
当 CNAME 或别名记录配置为指向没有匹配桶的 S3 端点时，任何 AWS 用户都可以创建该桶并在配置的别名下发布内容，即使拥有权不同也是如此。  
出于同样的原因，我们建议您在删除桶时更改或移除相应的 CNAME 或别名。

## 如何将主机名与 Amazon S3 桶关联
<a name="VirtualHostingCustomURLsHowTo"></a>

**使用 CNAME 将主机名与 Amazon S3 桶关联**

1. 选择属于您控制的域的主机名。

   本示例使用 `images` 域的 `example.com` 子域。

1. 创建与主机名匹配的存储桶。

   在本示例中，主机名和存储桶名称是 `images.example.com`。存储桶名称必须与主机名*精确* 匹配。

1. 创建一条 CNAME DNS 记录，它将主机名定义为 Amazon S3 桶的别名。

   例如：

   `images.example.com CNAME images.example.com.s3.us-west-2.amazonaws.com`
**重要**  
出于请求路由原因，CNAME DNS 记录必须严格按照上述示例所示进行定义。否则，它可能显示为正常运行，但将最终导致不可预测的行为。

   配置 CNAME DNS 记录的过程取决于您的 DNS 服务器或 DNS 提供商。有关特定信息，请参阅您的服务器文档或与您的供应商联系。

## 限制
<a name="VirtualHostingLimitations"></a>

 Amazon S3 的 SOAP API 不适用于新客户，并将于 2025 年 8 月 31 日接近使用寿命终止（EOL）。我们建议您使用 REST API 或 AWS 开发工具包。

## 向后兼容性
<a name="VirtualHostingBackwardsCompatibility"></a>

以下各节介绍了 Amazon S3 向后兼容性的各个方面，这些方面与路径类型和虚拟托管类型 URL 请求相关。

### 传统终端节点
<a name="s3-legacy-endpoints"></a>

某些区域支持传统终端节点。您可能会在服务器访问日志或 AWS CloudTrail 日志中看到这些端点。有关更多信息，请查看以下信息。有关 Amazon S3 区域和端点的完整列表，请参阅《Amazon Web Services 一般参考》**中的 [Amazon S3 端点和限额](https://docs.aws.amazon.com/general/latest/gr/s3.html)。

**重要**  
尽管您可能会在日志中看到传统终端节点，但我们建议您始终使用标准终端节点语法访问存储桶。  
Amazon S3 虚拟托管类型 URL 使用以下格式：  

```
https://bucket-name.s3.region-code.amazonaws.com/key-name
```
在 Amazon S3 中，路径类型 URL 使用以下格式：  

```
https://s3.region-code.amazonaws.com/bucket-name/key-name
```

#### s3‐区域
<a name="s3-dash-region"></a>

一些较旧的 Amazon S3 区域支持在 `s3` 和区域代码之间包含短划线 (`-`) 而不是点（例如 `s3.us-west-2`）的端点（例如 `s3‐us-west-2`）。如果您的存储桶位于这些区域之一，您可能会在服务器访问日志或 CloudTrail 日志中看到以下终端节点格式：

```
https://bucket-name.s3-region-code.amazonaws.com
```

在此示例中，存储桶名称为 amzn-s3-demo-bucket1，区域为美国西部（俄勒冈）：

```
https://amzn-s3-demo-bucket1.s3-us-west-2.amazonaws.com
```

#### 传统全局端点
<a name="deprecated-global-endpoint"></a>

对于某些区域，可以使用传统全局端点来构建未指定特定于区域的端点的请求。传统全局终端节点如下所示：

```
bucket-name.s3.amazonaws.com
```

在服务器访问日志或 CloudTrail 日志中，您可能会看到使用传统全局终端节点的请求。在此示例中，桶名称为 `amzn-s3-demo-bucket1`，传统全局端点为：

```
https://amzn-s3-demo-bucket1.s3.amazonaws.com
```

**美国东部（弗吉尼亚州北部）的虚拟托管类型请求**  
原定设置情况下，使用传统全局端点发出的请求会转到美国东部（弗吉尼亚州北部）。因此，传统全局终端节点有时用于替代美国东部（弗吉尼亚北部）的区域终端节点。如果您在美国东部（弗吉尼亚州北部）创建桶并使用全局端点，则原定设置情况下，Amazon S3 会将您的请求路由到此区域。

**其他区域的虚拟托管类型请求**  
传统全局端点也用于其他受支持的区域中的虚拟托管类型请求。当您在 2019 年 3 月 20 日之前发布的区域中创建桶并使用传统全局端点时，Amazon S3 将更新 DNS 记录以将请求重新路由到正确的位置，这可能会花费一些时间。同时，将应用原定设置规则，您的虚拟托管类型请求将转到美国东部（弗吉尼亚州北部）区域。然后，Amazon S3 将使用 HTTP 307 临时重定向将它重定向到正确的区域。

对于在 2019 年 3 月 20 日之后发布的区域中的 S3 桶，DNS 服务器不会将您的请求直接路由到您的桶所在的 AWS 区域。它而是会返回 HTTP 400 错误请求错误。有关更多信息，请参阅《Amazon S3 API 参考》**中的 [Making requests](https://docs.aws.amazon.com/AmazonS3/latest/API/MakingRequests.html)。

**路径类型请求**  
对于美国东部（弗吉尼亚州北部）区域，可以将传统全局端点用于路径类型请求。

对于所有其他区域，路径类型语法要求您在尝试访问存储桶时使用特定于区域的终端节点。如果您尝试访问具有传统全局端点的存储桶或与存储桶所在区域的端点不同的其它端点，您会收到 HTTP 响应代码“301 永久重定向”错误和一条消息（指示您资源的正确 URI）。例如，如果您将 `https://s3.amazonaws.com/bucket-name` 用于在美国西部（俄勒冈州）区域创建的存储桶，您将收到“HTTP 301 永久重定向”错误。