通过Cloudfront将文件上传到S3

时间:2016-10-21 19:43:45

标签: file-upload amazon-s3 amazon-cloudfront

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

def merge_files(path):
    ''' mergers txt files into one  main file'''
    now = datetime.datetime.now()
    date = ("%s_%s_%s_") %(now.month,now.day,now.year)
    files_to_merge = os.listdir(path)
    merged_file_list = []
    counter = 1
    for file in files_to_merge:
        if file.endswith(".txt"):
            with open(path+("file"+str(counter))+".txt","r") as files:
                files = files.readlines()
                merged_file_list.append(files)
                counter = counter + 1
    new_list = ("\n").join(["".join(x) for x in merged_file_list])
    print (new_list)
    with open (path + date + "final.txt" ,"w") as final:
        return final.write(new_list)

我创建了Cloudfront发行版。以下是可能很重要的配置:

一般:

<?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>

起源:

Delivery Method: Web
Alternate Domain Names (CNAMEs) files.example.com

行为:

Origin Domain Name: my-files.s3.amazonaws.com
Restrict Bucket Access: Yes
Grant Read Permissions on Bucket: Yes, Update Bucket Policy

我可以为文件下载创建签名的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。

是否可以将Cloudfront与已签名的URL一起用于上传文件?如何设置允许的来源以允许从localhost上传文件?

1 个答案:

答案 0 :(得分: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);
    }
 });