操作场景
在对象存储的实际应用中,通常需要在浏览器网页中访问存储在服务器上的数据。如果浏览器禁止跨域请求,则无法直接访问对象存储中的数据。
在ZOS中,您可以创建一个存储桶(bucket)来存储你的数据对象(Object),这些对象可以通过一个公共的URL进行访问。然而,如果您想在一个不同域的Web应用中直接访问这些对象,您可能会遇到跨域问题。例如,网站A要从ZOS存储桶中获取一个图片对象,在没有配置CORS的情况下,浏览器会因为跨域问题而阻止这个请求。然而您可以在存储桶配置中添加一个CORS策略,指定网站A可以访问您的对象。这样,该网站的Web应用就可以通过公共URL直接访问存储桶中的对象,而不会遇到跨域问题。
背景知识
浏览器同源策略
浏览器的同源策略是一种安全机制,用于限制一个网页文档或脚本与不同源的资源进行交互。同源策略的目的是保护用户的隐私和安全,防止恶意网站通过脚本访问其他网站的敏感信息或进行恶意操作。
根据同源策略,浏览器只允许当前网页与同一源下的其他资源进行交互,包括读取和修改。这种限制有效地保护了用户的隐私和安全,阻止恶意网站通过跨域请求获取用户的敏感信息。同时,同源策略也有助于防止跨站点脚本攻击(XSS)和跨站请求伪造攻击(CSRF)等网络安全问题。
网址同源是指两个URL具有相同的来源。具体来说,如果一个URL的协议、域名和端口号都与另一个URL相同,那么这两个URL就是同源的。下面将举例为您解释网址同源的概念:
- https://www.ctyun.cn 与 http://www.ctyun.cn 协议不同,为不同源;
- https://www.ctyun.cn 与https://www.ctyun.com域名不同,为不同源;
- https://www.ctyun.cn:80 与 https://www.ctyun.cn:81 端口号不同,为不同源;
- https://www.ctyun.cn/page.html 与 https://www.ctyun.cn/other.html 为同源。
跨域资源共享
跨域资源共享CORS(Cross-Origin Resource Sharing)是一种机制,允许一个域上的网页从不同源上获取资源。CORS通过在服务器上设置HTTP头信息,告诉浏览器允许或拒绝来自不同源的请求。这个机制允许Web应用从不同的源请求和获取数据。
CORS类型
浏览器将CORS请求分为两种类型:简单请求(simple request)和非简单请求(not-so-simple request)。
- 简单请求是指同时满足以下两个条件的请求:
- 请求方法是以下三种方法之一:HEAD、GET、POST。
- HTTP的头信息不超出以下几种字段:Accept、Accept-Language、Content-Language、Content-Type、DPR、Downlink、Save-Data、Viewport-Width、Width。其中,Content-Type的值只能是以下三种类型之一:text/plain、multipart/form-data、application/x-www-form-urlencoded。
- 非简单请求是指不满足以上两个条件的请求。当浏览器检测到一次请求是复杂情况时,会首先使用OPTIONS方法发起一个预检请求(preflight request)到服务器,以获知服务器是否允许本次请求。服务器根据预先设定的CORS策略进行判断,如果允许,就会在响应中添加相应的头信息,告诉浏览器允许跨域请求。然后,浏览器就会发出实际的请求。
方案优势
通过配置浏览器跨域访问具有以下优势:
- 增强互操作性:跨域访问的配置可以使不同的系统、应用程序和平台之间更容易地进行数据交互。这将提高互操作性,使得数据可以在各种不同的环境中自由流动。
- 提高可访问性:允许跨域访问可以使来自不同域的对象存储桶对设置允许访问的浏览器和客户端可见。这将提高应用程序的可访问性,使得更多的用户可以访问和使用这些资源。
- 简化开发流程:解决跨域问题可以简化开发流程,减少开发人员需要处理的问题。这将提高开发效率,加速应用程序的开发和部署。
- 提高安全性:配置跨域策略可以限制未经授权的访问,减少数据泄露的风险。这将提高应用程序的安全性,保护用户数据不被非法获取或滥用。
- 优化性能:通过允许跨域访问,浏览器可以直接从对象存储桶中获取资源,而不需要进行额外的网络请求。这将优化应用程序的性能,提高响应速度和用户体验。
操作步骤
借助CORS支持,您可以使用ZOS构建各种客户端Web应用程序,并选择性地允许跨域访问您的ZOS资源。要将您的桶配置为允许跨域请求,您可以将CORS规则配置添加到桶中。本节将向您介绍如何使用ZOS控制台和ZOS软件开发工具包的方式来启用CORS。
使用ZOS控制台
前提:用户注册天翼云账号并开通对象存储服务。
注意:在桶上启用CORS,访问控制列表(ACL)和其他访问权限策略仍适用。
1.使用以下网址打开ZOS 控制台:https://console.ctyun.cn/console/index/#/ebs/zos/v2/bucketList
2.选择您要配置CORS的桶,点击Bucket名称进入“概览”页面;
3.点击“权限管理”->“跨域设置”->“设置”进入策略配置界面;
4.单击“创建策略”后点击“确定”按钮保存规则。
您可以配置CORS的以下各项参数:
参数 | 描述 |
---|---|
来源 | 设定允许跨境请求的来源,每行一个,每行最多存在一个通配符*。 |
允许Methods | 设定允许的跨域请求方法,包含:GET、POST、DELETE、PUT、HEAD。 |
允许Headers | 设定允许的跨域请求header,每行一个,每行最多存在一个通配符*。 |
暴露Headers | 设定允许从应用程序进行访问的响应头部。 |
缓存时间(秒) | 设定浏览器对特定资源的预取(OPTIONS)请求返回结果的缓存时间。 |
使用ZOS软件开发工具包
下面展示JAVA SDK的使用案例:
使用SDK需要您在您的机器上配置好java以及Maven等环境,具体操作请参考JAVA SDK文档
您可以使用setBucketCrossOriginConfiguration设置跨域规则,并分别通过 getBucketCrossOriginConfiguration 、deleteBucketCrossOriginConfiguration方法获取或删除您桶上的跨域访问规则。
import com.amazonaws.ClientConfiguration;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.Protocol;
import com.amazonaws.services.s3.model.*;
import java.util.ArrayList;
import java.util.List;
public class CORS {
public static String ACCESS_KEY = "AK";//此处请改成您的AK
public static String SECRET_KEY = "SK";//此处请改成您的SK
public static String END_POINT = "End_Point";//此处请改成您桶对应的EndPoint
public static String BUCKET_NAME = "bucket-ff177";
public static void main(String[] string){
AmazonS3 s3Client = null;
try {
// 当使用HTTPS协议且采用自签名认证时,需关闭证书检查
// System.setProperty("com.amazonaws.sdk.disableCertChecking", "true");
// 使用凭据和配置建立连接
AWSCredentials credentials = new BasicAWSCredentials(ACCESS_KEY, SECRET_KEY);
ClientConfiguration awsClientConfig = new ClientConfiguration();
// 使用V2签名时,采用"S3SignerType"
awsClientConfig.setSignerOverride("S3SignerType");
// 使用V4签名时,采用"AWSS3V4SignerType"
//awsClientConfig.setSignerOverride("AWSS3V4SignerType");
// 连接默认使用HTTPS协议,使用HTTP协议连接时需要显式指定
awsClientConfig.setProtocol(Protocol.HTTP);
s3Client = AmazonS3ClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(credentials))
.withClientConfiguration(awsClientConfig)
.withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(END_POINT, ""))
.disableChunkedEncoding()
.build();
System.out.print("=====connect success=====\n");
}catch (Exception e) {
System.out.print("=====request fail=====\n");
System.out.print(e.getMessage());
}
// setBucketCrossOriginConfiguration
CORSRule rule = new CORSRule();
rule.setId("test1");
rule.setAllowedMethods(CORSRule.AllowedMethods.GET,CORSRule.AllowedMethods.PUT);
List orgs = new ArrayList();
orgs.add("*");
rule.setAllowedOrigins(orgs);
BucketCrossOriginConfiguration config = new BucketCrossOriginConfiguration();
List<CORSRule> lr = new ArrayList<CORSRule>();
lr.add(rule);
config.setRules(lr);
SetBucketCrossOriginConfigurationRequest req =
new SetBucketCrossOriginConfigurationRequest(BUCKET_NAME,config);
s3Client.setBucketCrossOriginConfiguration(req);
// getBucketCrossOriginConfiguration
GetBucketCrossOriginConfigurationRequest req1 =
new GetBucketCrossOriginConfigurationRequest(BUCKET_NAME);
BucketCrossOriginConfiguration config1 = s3Client.getBucketCrossOriginConfiguration(req1);
// deleteBucketCrossOriginConfiguration
DeleteBucketCrossOriginConfigurationRequest req2 =
new DeleteBucketCrossOriginConfigurationRequest(BUCKET_NAME);
s3Client.deleteBucketCrossOriginConfiguration(req2);
}
}
实践案例
下面我们将以GET请求为例展示配置CORS前后跨域访问ZOS桶内资源的情况。
前提条件
- 登录ZOS控制台创建桶-bucket-ff177,并设置其ACL权限为“公有读”。上传一个名为"hello.txt"的文件,文件内容为“Hello World!";
- 点击文件后获取该图片的访问链接:https://beijing-5.zos.ctyun.cn/bucket-ff177/hello.txt
- 禁用浏览器缓存:以Chrome为例, 按F12打开调试者工具,在调试者工具的右上角打开菜单选项,选择更多工具(More tools)->网络限制 (Network conditions),在界面中勾选“停用缓存”选项,即可禁用浏览器缓存。
- Fetch API:Fetch API 是一个现代的网络请求API,可以用于替代浏览器中的XMLHttpRequest。Fetch API 支持CORS(跨源资源共享),因此可以用于发送跨域请求。
实践步骤
1.在终端输入curl https://beijing-5.zos.ctyun.cn/bucket-ff177/hello.txt
返回结果正常,说明访问情况正常;
2.采用静态html页面利用Fetch API模拟跨域访问该Object,在桌面创建一个名为test的文件,后缀为html,文件内容如下:
<!DOCTYPE html>
<html>
<head>
<title>Send Get Request</title>
<style> body { display: flex; justify-content: center; align-items: center; height: 100vh; font-family: Arial, sans-serif; } button { margin: 20px; padding: 10px 20px; font-size: 1.2rem; border: none; border-radius: 5px; background-color: #008CBA; color: white; cursor: pointer; } button:hover { background-color: #007B9E; } </style>
</head>
<body>
<button onclick="sendGetCorsRequest()">Send Get Request</button>
<script type="text/javascript">
var url = "https://beijing-5.zos.ctyun.cn/bucket-ff177/hello.txt";
function sendGetCorsRequest() {
fetch(url, {
method: "GET",
headers:{"Content-Type": "application/json",}
}).then(function(res) {
if (res.ok) {
alert("The response is ok, get request success!");
} else {
alert("The response wasn't ok, got status ", res.status);
}
}, function(e) {
alert("Get request failed!", e);
}).finally(() => {
location.reload();
});
}
</script>
</body>
</html>
3.采用Chrome浏览器打开test.html文件并点击“Send Get Request”按钮,访问失败。
这个错误信息表示,请求的资源由于缺少 “Access-Control-Allow-Origin”头部而被CORS(跨源资源共享)策略阻止。这通常发生在尝试从不同的域获取资源时,浏览器会检查请求是否符合CORS策略。
4.在控制台配置下方的跨域资源共享规则,接受如下请求来源以及请求方法,具体规则如下:
5.重新使用浏览器打开test.html文件,访问成功。