我有两个存储桶,一个是私有的,一个是公共的。私人将拥有带有 CannedAccessControlList.Private 的文件,而公共将拥有带有 CannedAccessControlList.PublicRead 的文件。除了这些,它们都是一样的。
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>Authorization</AllowedHeader>
</CORSRule>
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>PUT</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
AmazonS3 s3client = new AmazonS3Client(new BasicAWSCredentials(AWS_ACCESS_KEY,AWS_SECRET_KEY));
generatePresignedUrlRequest = new GeneratePresignedUrlRequest(AWS_BUCKET_PRIVATE_NAME, path,HttpMethod.PUT);
generatePresignedUrlRequest.setExpiration(expiration);
generatePresignedUrlRequest.putCustomRequestHeader("x-amz-acl", CannedAccessControlList.Private.toString());
generatePresignedUrlRequest.putCustomRequestHeader("content-type", fileType);
url = s3client.generatePresignedUrl(generatePresignedUrlRequest);
Run Code Online (Sandbox Code Playgroud)
我可以在以下场景中将文件上传到 s3。默认情况下,所有生成的 URL 都是 https。1. 带有 https 的私有存储桶 2. 公共存储桶通过 https 失败,将 https 替换为 http 就可以了。
为什么公共存储桶上传失败 https 的问题。我无法在生产系统上使用 http,因为它安装了 ssl。
我学到了两件事。
虚拟主机风格
https://xyz.com.s3.amazonaws.com/myObjectKey
路径样式
https://s3.amazonaws.com/xyz.com/myObjectKey
如果您在 https 上,上传文件的 Ajax 调用在第一种情况下会失败,因为 SSL 证书仅对 s3.amazonaws.com 有效,并且如果存储桶名称(如主机名)SSL 检查将失败并阻止 ajax 上传调用。
在 Java 中解决此问题
s3client.setS3ClientOptions(new S3ClientOptions().withPathStyleAccess(true));
Run Code Online (Sandbox Code Playgroud)
在稍后的情况下,您上传将再次失败并提到 CORS 问题,如果您预签名的 URL 是 s3.amazonaws.com,并且即使您在存储桶中启用了 CORS,它也不会选择“访问控制允许来源”。因此,您需要确保使用以下代码提供正确的区域名称。
s3client.setEndpoint("s3-ap-southeast-1.amazonaws.com");//or whatever region you bucket is in.
Run Code Online (Sandbox Code Playgroud)
参考:http : //shlomoswidler.com/2009/08/amazon-s3-gotcha-using-virtual-host.html