应用场景
浏览器限制脚本内发起跨源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字体或图片,让这些资源能被多个网站共享。
前提条件
开通对象存储(经典版)Ⅰ型服务。
具体操作
确定是否同源
如果两个网页的协议、域名、端口(若指定了端口)相同,视为同源。下表给出了相对https://www.ctyun.cn/test/page.html的同源检测示例:
URL | 结果 | 原因 |
---|---|---|
https://www.ctyun.cn/test2/page.html | 成功 | 协议、域名、端口相同 |
https://www.ctyun.cn/test/inner/page.html | 成功 | 协议、域名、端口相同 |
http://www.ctyun.cn/test/page.html | 失败 | 协议不同 ( HTTPS ) |
https://www.ctyun.cn:81/test/page.html | 失败 | 端口不同 ( 81 ) |
https://newwww.ctyun.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的访问地址为http://example-bucket.oos-cn.ctyunapi.cn/testcors.txt。
使用curl直接访问该文本文档,请将以下地址替换为您的文件地址:
curl http://example-bucket.oos-cn.ctyunapi.cn/testcors.txt
返回testcors.txt 文件的内容:testcors。表示该文档可以正常访问。
[root@user~]#curl http://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 = 'http://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配置。