應用場景
瀏覽器限制腳本內發起跨源HTTP請求,即同源策略。例如,當來自于A網站的頁面中的JavaScript代碼希望訪問B網站的時候,瀏覽器會拒絕該訪問,因為A、B兩個網站是屬于不同的域。通過配置跨域資源共享(Cross-Origin Resource Sharing,CORS),可以解決不同域相互訪問的問題,CORS定義了客戶端Web應用程序在一個域中與另一個域中的資源進行交互的方式。
CORS可以應用下列場景:
- 通過CORS支持,使用JavaScript和HTML5來構建Web應用,直接訪問OOS中的資源,而不再需要代理服務器做中轉。
- 使用HTML5中的拖拽功能,直接向OOS上傳文件,展示上傳進度,或是直接從Web應用中更新內容。
- 托管在不同域中的外部網頁、樣式表和HTML5應用,現在可以引用存儲在OOS中的Web字體或圖片,讓這些資源能被多個網站共享。
前提條件
開通對象存儲(經典版)Ⅰ型服務。
具體操作
確定是否同源
如果兩個網頁的協議、域名、端口(若指定了端口)相同,視為同源。下表給出了相對//www.daliqc.cn/test/page.html的同源檢測示例:
| URL | 結果 | 原因 |
|---|---|---|
| //www.daliqc.cn/test2/page.html | 成功 | 協議、域名、端口相同 |
| //www.daliqc.cn/test/inner/page.html | 成功 | 協議、域名、端口相同 |
| //www.daliqc.cn/test/page.html | 失敗 | 協議不同 ( HTTPS ) |
| //www.daliqc.cn:81/test/page.html | 失敗 | 端口不同 ( 81 ) |
| //newwww.daliqc.cn/page.html | 失敗 | 域名不同 |
OOS支持的CORS
OOS支持存儲桶(Bucket)級別的CORS配置,用戶可以根據需求,配置CORS規則允許或者拒絕相應的跨域請求。
CORS請求的能否通過與OOS的身份驗證等是相互獨立的。OOS的CORS 規則僅僅是用來決定是否附加CORS相關的Header的一個規則,是否攔截該請求完全由瀏覽器決定。
注意
每個Bucket最多可以配置100條跨域規則。
當OOS收到一個跨域請求(或者OPTIONS請求)時,會讀取Bucket對應的CORS規則,然后進行相應的權限檢查。OOS會依次檢查每一條規則,使用第一條匹配的規則來允許請求并返回對應的Header。如果所有規則都匹配失敗,則不附加任何CORS相關的Header。
配置示例
本示例介紹使用網頁從OOS獲取數據的配置步驟。示例中使用的存儲桶(Bucket)權限設置公共讀(Public-Read),其余配置相同。以下示例中使用的存儲桶名為example-bucket,存儲桶訪問權限為公共讀,訪問權限為私有的存儲桶只需要在請求中附加簽名。
確認文件可正常訪問
上傳一個testcors.txt的文本文檔到example-bucket。testcors.txt的訪問地址為//example-bucket.oos-cn.ctyunapi.cn/testcors.txt。
使用curl直接訪問該文本文檔,請將以下地址替換為您的文件地址:
curl //example-bucket.oos-cn.ctyunapi.cn/testcors.txt
返回testcors.txt 文件的內容:testcors。表示該文檔可以正常訪問。
[root@user~]#curl //example-bucket.oos-cn.ctyunapi.cn/testcors.txt
testcors
使用網頁來訪問文件
-
使用創建一個HTML文件來直接訪問該testcors.txt文件。
寫一個HTML文件,將以下代碼復制到本地保存成HTML文件后使用瀏覽器打開。因為沒有設置自定義的頭,因此該請求不需要預檢。
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> </head> <body> <a href="javascript:testcors()">Test CORS</a> <script> function testcors() { var url = '//example-bucket.oos-cn.ctyunapi.cn/testcors.txt'; var xhr = new XMLHttpRequest(); xhr.open('HEAD', url); xhr.onload = function () { var headers = xhr.getAllResponseHeaders().replace(/\r\n/g, '\n'); alert('request success, CORS allow.\n' + 'url: ' + url + '\n' + 'status: ' + xhr.status + '\n' + 'headers:\n' + headers); }; xhr.onerror = function () { alert('request error, maybe CORS error.'); }; xhr.send(); } </script> </body> </html> -
在瀏覽器中打開該HTML文件,單擊 Test CORS 發送請求后,出現以下錯誤,錯誤提示:無權限訪問,原因是沒有找到 Access-Control-Allow-Origin 這個 Header。顯然,這是因為服務器沒有配置 CORS。
-
訪問失敗,進入標頭(Header)界面檢查原因,可以看到瀏覽器發送了帶Origin的Request,因此是一個跨域請求。
設置CORS
通過設置存儲桶的CORS可以解決跨域請求。
可以在OOS控制臺設置CORS。下面示例為通過控制臺設置CORS。若您的CORS設置不是特別復雜,也建議使用控制臺進行CORS設置。
- 登錄 OOS控制臺,單擊“存儲桶列表”,進入相關的存儲桶,單擊“屬性”操作,選擇“跨域設置”。
- 單擊“添加規則”,添加第一條規則,使用最寬松的配置如下。
注意CORS設置可以由多條規則組成,OOS會從第一條開始逐條匹配,以最早匹配上的規則為準。

驗證結果
配置完成后,重新嘗試訪問 testcors.txt 文本文件。結果如下,可以正常訪問請求。
故障排除及意見
如果想排除因跨域帶來的訪問問題,可以為存儲桶設置最寬松的CORS,允許所有的跨域請求。如果該配置下依然訪問出錯,則可以確定不是在CORS出錯,而是在其他部分。
除了最寬松的CORS設置外,您還可以配置更精細的控制機制來實現針對性的控制,為了安全性,建議您根據自己的使用場景,使用最小的CORS配置。