

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 對 CORS 進行故障診斷
<a name="cors-troubleshooting"></a>

下列主題可協助您針對一些與 S3 相關的常見 CORS 問題進行疑難排解。

**Topics**
+ [403 Forbidden 錯誤 - 此儲存貯體未啟用 CORS](#cors-not-enabled)
+ [403 Forbidden 錯誤 - 不允許此 CORS 請求](#cors-not-enabled)
+ [在 CORS 回應中找不到標頭](#Headers-not-found)
+ [S3 Proxy 整合上 CORS 的考量](#cors-in-proxy)

## 403 Forbidden 錯誤：此儲存貯體未啟用 CORS
<a name="cors-not-enabled"></a>

當跨原始伺服器請求傳送至 Amazon S3，但 S3 儲存貯體上未設定 CORS 時，會發生下列 `403 Forbidden` 錯誤。

 錯誤：HTTP/1.1 403 Forbidden 的 CORS 回應：此儲存貯體未啟用 CORS。

CORS 組態是具有規則的文件或政策，這些規則可以識別允許您存取您儲存貯體的原始伺服器、每個原始伺服器支援的操作 (HTTP 方法)，以及其他操作特定資訊。了解如何使用 Amazon S3 主控台、 AWS SDKs 和 REST API 在 S3 上[設定 CORS](https://docs.aws.amazon.com/AmazonS3/latest/userguide/enabling-cors-examples.html)。 Amazon S3 如需 CORS 的詳細資訊和 CORS 組態的範例，請參閱 [CORS 元素](https://docs.aws.amazon.com/AmazonS3/latest/userguide/ManageCorsUsing.html#cors-example-1)。

## 403 Forbidden 錯誤：不允許此 CORS 請求
<a name="cors-not-enabled"></a>

當 CORS 組態中的 CORS 規則與請求中的資料不相符時，就會收到下列 `403 Forbidden` 錯誤。

錯誤：HTTP/1.1 403 Forbidden 的 CORS 回應：不允許此 CORS 請求。

因此，此 `403 Forbidden` 錯誤可能是由多種原因所導致：
+ 不允許原始伺服器。
+ 不允許方法。
+ 不允許請求的標頭。

對於 Amazon S3 收到的每個請求，您必須在 CORS 組態中擁有符合請求中資料的 CORS 規則。

### 不允許原始伺服器
<a name="Origin-not-allowed"></a>

 對儲存貯體發出之 CORS 請求中的 `Origin` 標頭，必須符合 CORS 組態中 `AllowedOrigins` 元素的原始伺服器。`AllowedOrigins` 元素中的萬用字元 (`"*"`) 會符合所有 HTTP 方法。如需如何更新 `AllowedOrigins` 元素的詳細資訊，請參閱[設定跨原始伺服器資源共用 (CORS)](https://docs.aws.amazon.com/AmazonS3/latest/userguide/enabling-cors-examples.html)。

 例如，如果只有將 `http://www.example1.com` 網域包含在 `AllowedOrigins` 元素中，則從 `http://www.example2.com` 網域傳送的 CORS 請求會收到 `403 Forbidden` 錯誤。

下列範例顯示包含 `AllowedOrigins` 元素中 `http://www.example1.com` 網域的部分 CORS 組態。

```
"AllowedOrigins":[
   "http://www.example1.com"
]
```

若要讓從 `http://www.example2.com` 網域傳送的 CORS 請求成功，`http://www.example2.com` 網域應包含在 CORS 組態的 `AllowedOrigins` 元素中。

```
"AllowedOrigins":[
   "http://www.example1.com"
   "http://www.example2.com"
]
```

### 不允許方法
<a name="Methods-not-allowed"></a>

 在對儲存貯體發出之 CORS 請求的 `Access-Control-Request-Method` 中指定的 HTTP 方法，必須符合 CORS 組態中 `AllowedMethods` 元素列出的方法。`AllowedMethods` 中的萬用字元 (`"*"`) 會符合所有 HTTP 方法。如需如何更新 `AllowedOrigins` 元素的詳細資訊，請參閱[設定跨原始伺服器資源共用 (CORS)](https://docs.aws.amazon.com/AmazonS3/latest/userguide/enabling-cors-examples.html)。

在 CORS 組態中，您可以在 `AllowedMethods` 元素中指定下列方法。
+ `GET`
+ `PUT`
+ `POST`
+ `DELETE`
+ `HEAD`

下列範例顯示 CORS 組態的一部分內容，其中包含 `AllowedMethods` 元素中的 `GET` 方法。只有包含 `GET` 方法的請求才會成功。

```
"AllowedMethods":[
   "GET"
]
```

 如果將 HTTP 方法 (例如 `PUT`) 用於 CORS 請求，或包含在傳送至您儲存貯體的預檢 CORS 請求中，但該方法不存在於您的 CORS 組態中，則請求會導致 `403 Forbidden` 錯誤。若要允許此 CORS 請求或 CORS 預檢請求，則必須將 `PUT` 方法新增至您的 CORS 組態。

```
"AllowedMethods":[
   "GET"
   "PUT"
]
```

### 不允許請求的標頭
<a name="Headers-not-allowed"></a>

 預檢請求的 `Access-Control-Request-Headers` 標頭中列出的標頭，必須符合 CORS 組態的 `AllowedHeaders` 元素中的標頭。如需可用於 Amazon S3 請求的常見標頭清單，請參閱[常見請求標頭](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTCommonRequestHeaders.html)。如需如何更新 `AllowedHeaders` 元素的詳細資訊，請參閱[設定跨原始伺服器資源共用 (CORS)](https://docs.aws.amazon.com/AmazonS3/latest/userguide/enabling-cors-examples.html)。

下列範例顯示包含 `AllowedHeaders` 元素中 `Authorization` 標頭的部分 CORS 組態。只有 `Authorization` 標頭的請求會成功。

```
"AllowedHeaders":  [
    "Authorization"
]
```

 如果將標頭 (例如 `Content-MD5`) 包含在 CORS 請求中，但該標頭不存在於您的 CORS 組態中，則請求會導致 `403 Forbidden` 錯誤。若要允許此 CORS 請求，必須將 `Content-MD5` 標頭新增至您的 CORS 組態。如果您想要將 CORS 請求中的 `Authorization` 和 `Content-MD5` 標頭同時傳遞至儲存貯體，請確認兩個標頭都包含在 CORS 組態的 `AllowedHeaders` 元素中。

```
"AllowedHeaders":  [
    "Authorization"
    "Content-MD5"
]
```

## 在 CORS 回應中找不到標頭
<a name="Headers-not-found"></a>

 CORS 組態中的 `ExposeHeaders` 元素會識別您想要讓指令碼和應用程式 (在瀏覽器中執行) 存取的回應標頭，以回應 CORS 請求。

如果儲存在 S3 儲存貯體中的物件具有使用者定義的中繼資料 (例如 `x-amz-meta-custom-header`) 以及回應資料，則此自訂標頭可能包含您希望從用戶端 JavaScript 程式碼存取的其他中繼資料或資訊。不過，瀏覽器預設會基於安全考量封鎖對自訂標頭的存取。若要允許用戶端 JavaScript 存取自訂標頭，您需要在 CORS 組態中包含標頭。

 在下面的範例中，`x-amz-meta-custom-header1` 標頭包含在 `ExposeHeaders` 元素中。`x-amz-meta-custom-header2` 不包含在 `ExposeHeaders` 元素中，而且不存在於 CORS 組態內。回應中只會傳回包含在 `ExposeHeaders` 元素中的值。如果請求在 `x-amz-meta-custom-header2` 標頭中包含 `Access-Control-Expose-Headers` 標頭，回應仍會傳回 `200 OK`。不過，這只會傳回允許的標頭 (例如 `x-amz-meta-custom-header`)，並會顯示在回應中。

```
"ExposeHeaders":  [
    "x-amz-meta-custom-header1"
]
```

 為了確保回應中顯示所有標頭，請將所有允許的標頭新增至 CORS 組態中的 `ExposeHeaders` 元素，如下所示。

```
"ExposeHeaders":  [
    "x-amz-meta-custom-header1",
    "x-amz-meta-custom-header2"
]
```

## S3 Proxy 整合上 CORS 的考量
<a name="cors-in-proxy"></a>

如果您遇到錯誤，並已檢查 S3 儲存貯體上的 CORS 組態，且跨來源請求會傳送至代理，例如 AWS CloudFront，請嘗試下列動作：
+ 設定設定以允許 HTTP 請求的 `OPTIONS` 方法。
+ 設定 Proxy 以轉送下列標頭：`Origin`、`Access-Control-Request-Headers` 及 `Access-Control-Request-Method`。
+ 設定代理設定，將原始伺服器標頭包含在其快取鍵中。這很重要，因為快取代理若在其快取鍵中未包含原始伺服器標頭，可能會提供未包含不同原始伺服器之適當 CORS 標頭的快取回應。

部分 Proxy 可為 CORS 請求提供預先定義的功能。例如，在 CloudFront 中，您可以設定包含標頭的政策 

 當原始伺服器為 Amazon S3 儲存貯體時，啟用跨原始伺服器資源共用 (CORS) 請求。

 此政策包括下列設定：
+ 原始伺服器請求中包含的標頭：

   `Origin`

   `Access-Control-Request-Headers`

   `Access-Control-Request-Method`
+ 原始伺服器請求中包含的 Cookie：無
+ 原始伺服器請求中包含的查詢字串：無

如需詳細資訊，請參閱《CloudFront 開發人員指南》**中的[使用政策控制原始伺服器請求](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/controlling-origin-requests.htm)或[使用受管原始伺服器請求政策](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-managed-origin-request-policies.html#managed-origin-request-policy-cors-s3)。