設定 S3 CORS 完成跨域請求
設定 S3 CORS 完成跨域請求
跨來源資源共用(Cross-Origin Resource Sharing (CORS))是一種使用額外 HTTP 標頭令目前瀏覽網站的使用者代理取得存取其他來源(網域)伺服器特定資源權限的機制。當使用者代理請求一個不是目前文件來源——例如來自於不同網域(domain)、通訊協定(protocol)或通訊埠(port)的資源時,會建立一個跨來源 HTTP 請求(cross-origin HTTP request)。
舉個跨來源請求的例子:http://domain-a.com HTML 頁面裡面一個 <img>
標籤的 src 屬性載入來自 http://domain-b.com/image.jpg 的圖片。現今網路上許多頁面所載入的資源,如 CSS 樣式表、圖片影像、以及指令碼(script)都來自與所在位置分離的網域,如內容傳遞網路(content delivery networks, CDN)。
基於安全性考量,程式碼所發出的跨來源 HTTP 請求會受到限制。例如,XMLHttpRequest 及 Fetch 都遵守同源政策(same-origin policy)。這代表網路應用程式所使用的 API 除非使用 CORS 標頭,否則只能請求與應用程式相同網域的 HTTP 資源。
情境
- 在本教程中,我們將創建兩個 S3 Bucket,分別 Host 各自的靜態網頁,並且在 A Bucket 透過 Ajax 載入 B Bucket 的網頁內容,以此模擬跨域請求。我們會先嘗試尚未設定 CORS Configuration,將會看到錯誤訊息,再將 CORS Configuration 設定完成,查看結果。
準備事項
- AWS 帳號。
-
下載本教程中的檔案,可以到 cmd 當中輸入以下指令
$ git clone https://github.com/ecloudvalley/AWS-S3-CORS.git
創建 S3 Bucket 並上傳媒體檔案
現在,我們創建兩個 S3 Bucket 來模擬情境,由於 S3 Bucket 創建必須為獨一無二的命名,因此在 Host 靜態網頁時,兩個網頁就是不同的網域,基於同源政策,非同源之間目前共有三種行為受到限制(若想多了解同源政策請點擊連結)
- Cookie、LocalStorage 和 IndexDB 無法讀取。
- DOM 無法獲得。
- AJAX 請求不能發送。
雖然這些限制是必要的,但是有些時候很不方便,合理的用途也受到影響。以下將會介紹其中一種規避這三種限制的方法:CORS
- 登入至 AWS 主控台 AWS console
-
在 主控台上方, 點選 Services -> S3
-
點選 Create bucket
- 輸入 Bucket name :
<YOUR-BUCKET-NAME>
,在本教程當中稱為Bucket-1 > Bucket name 必須為獨一無二 -
選擇 Region,在此選擇 US East(N. Virginia) -> Create
-
創建完成之後,點選剛才創建的 Bucket, 點選 Properties
-
接著點選 Static website hosting,選擇 Use this bucket to host a website
- 在 index document 欄位輸入:
index.html
,在 error document 欄位輸入:error.html
- 選擇我們剛才創建的
Bucket-1
-
點選 **Upload** -> **Add files** -> 選擇從本教程下載的檔案(**load.html**)
-
Next -> Manage public permissions 選擇 Grant public read access to this object(s) -> Next -> Next -> Upload
-
觀看一下這個網頁上的內容
-
進入
Bucket-1
,點選 Properties -> Static website hosting -> 點選 Endpoint -
並且將 Endpoint 網址後方加上
/load.html
,顯示load.html
該網頁的媒體資料
- 接著創建第二個 Bucket,切記 Bucket name 不可重複,Bucket Name :
<YOUR-BUCKET-NAME>
,我們稱為Bucket-2
- 設定與第一個 Bucket 相同
- 並且只需要將 index.html error.html 上傳到
Bucket-2
> 記得選擇 “Grant public read access to this object(s)” > 如果忘了設定 public read access,可以回到 Bucket 內,將檔案勾選 -> Actions -> Make public 即可
尚未設定 S3 CORS 之前
-
我們的
index.html
的內容是會載入Bucket-1
內的load.html
媒體檔案,但在此我們尚未設定 CORS,先來看看在尚未設定 CORS 時,會出現什麼訊息 -
進入
Bucket-2
,點選 Properties -> Static website hosting -> 點選 Endpoint -
這時我們可以看到,並沒有成功載入
load.html
的網頁內容 -
我們可以在網頁點右鍵 -> 檢查,查看是什麼問題
-
或是瀏覽器上方,點選 檢視 -> 開發人員選項 -> JavaScript 控制台
-
會看到如圖所示的錯誤訊息,之所以會有錯誤訊息是因為在 index.html 當中, 我們使用 Ajax 載入 load.html,基於前面提及的同源政策,在我們尚未設定 CORS之前,跨域請求會被阻擋,於是無法載入 load.html 的內容
設定 S3 CORS
在前面已經示範了,尚未設定 CORS 會因為跨域請求而被阻擋,但有些時候我們必須要使用到跨域請求,例如:Web 應用本身是部署在不同的伺服器伺服器上、前後端的開發分離等等
- 進到 Bucket jonny-test-cors-media -> Permissions -> CORS configuration
-
複製以下代碼到 CORS configuration -> Save
< ?xml version=”1.0″ encoding=”UTF-8″?>
* GET 3000 Authorization -
重新整理剛才出現錯誤訊息的網頁,如果還是出現相同錯誤訊息,請先清除快取再重新整理
-
成功顯示出 jonny-test-cors-media 裡的 load.html
清除資源
僅需直接刪除兩個 Bucket 即可。
結論
現在你學會了如何設定 S3 Bucket 的 CORS,可以透過設定 CORS ,訪問在不同網域的資源,存取在不同 Domain 底下的 S3 Bucket 的內部資源!