通过Cloudfront将文件上传到S3

esh*_*lox 6 file-upload amazon-s3 amazon-cloudfront

我正在尝试通过Cloudfront将文件上传到S3.我创建了一个名为my-files的存储桶.Bucket CORS设置:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>PUT</AllowedMethod>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedMethod>DELETE</AllowedMethod>
        <AllowedMethod>HEAD</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>Authorization</AllowedHeader>
    </CORSRule>
</CORSConfiguration>
Run Code Online (Sandbox Code Playgroud)

我创建了Cloudfront发行版.这是可能很重要的配置:

一般:

Delivery Method: Web
Alternate Domain Names (CNAMEs) files.example.com
Run Code Online (Sandbox Code Playgroud)

起源:

Origin Domain Name: my-files.s3.amazonaws.com
Restrict Bucket Access: Yes
Grant Read Permissions on Bucket: Yes, Update Bucket Policy
Run Code Online (Sandbox Code Playgroud)

行为:

Path Pattern: Default (*)
Origin: S3-my-files
Viewer Protocol Policy: HTTP and HTTPS
Allowed HTTP Methods: GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE
Whitelist Headers: Access-Control-Request-Headers, Access-Control-Request-Method, Origin
Object Caching: Use Origin Cache Headers
Restrict Viewer Access (Use Signed URLs or Signed Cookies): Yes
Trusted Signers: Self
Run Code Online (Sandbox Code Playgroud)

我可以为文件下载创建签名URL,它可以正常工作.我可以为S3存储桶创建CNAME,使用预先签名的URL将文件上传到S3,这也可以正常工作.当我尝试通过Cloudfront上传文件时,我得到403响应(OPTIONS):

XMLHttpRequest无法加载http://files.example.com/.对预检请求的响应未通过访问控制检查:请求的资源上不存在"Access-Control-Allow-Origin"标头.因此不允许来源' http://0.0.0.0:5000 '访问.响应具有HTTP状态代码403.

是否可以将带有签名URL的Cloudfront用于上载文件?如何设置允许的来源以允许从localhost上传文件?

Tủn*_*Tủn 1

我怀疑该错误与您请求的 CORS 选项有关。

使用 jQuery,这是当前我的示例代码,它通过 CloudFront 成功将文件上传到 S3(注意该crossDomain选项)。如果你不使用jQuery,你可以基于此编写你的代码:

$.ajax({
    type: 'POST',
    url: 'YourGetSignatureMethod', //return your signed url
    data: {
          fileName: yourFileName,
          expiration: yourPolicyExpirationDate
    },
    success: function (signedUrl) {
         //signedUrl= 'http://sampleId.cloudfront.net/video.mp4?Policy=examplePolicy&Signature=exampleSignature&Key-Pair-Id=exampleKey'
         let fileObject = yourGetFileFunction(); //returns File API
         let reader = new FileReader(); //using the FileReader API to read files
         reader.onload = function () {                                      
	     $.ajax({
		url: signedUrl,
		type: 'PUT',
		contentType: fileObject.type,
		data: reader.result,
		processData: false,
		crossDomain: true,
                success: function(){
                //upload success
                }
	    });
        }  
        reader.readAsArrayBuffer(fileObject);
    }
 });
Run Code Online (Sandbox Code Playgroud)