首页 > 解决方案 > 使用 Django 为 S3 上传创建签名请求

问题描述

我在 heroku 上有一个简单的 django 应用程序,用于上传图像,从桌面访问时它按预期工作,但当我在移动设备上访问网站时,无法签署上传到 AWS S3 的请求。

签名代码如下所示:

def sign_s3(request):
    request = request.GET
    S3_BUCKET = os.environ.get('AWS_STORAGE_BUCKET_NAME')

    file_name = request.get('file_name')
    file_type = request.get('file_type')

    s3 = boto3.client('s3')

    presigned_post = s3.generate_presigned_post(
    Bucket = S3_BUCKET,
    Key = file_name,
    Fields = {"acl": "public-read", "Content-Type": file_type},
    Conditions = [
        {"acl": "public-read"},
        {"Content-Type": file_type}
    ],
    ExpiresIn = 3600
    )

    return HttpResponse(json.dumps({
    'data': presigned_post,
    'url': 'https://%s.s3.amazonaws.com/%s' % (S3_BUCKET, file_name)
    }))

我将 S3 存储桶中的所有内容设置为公开,并将 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>POST</AllowedMethod>
    <AllowedMethod>PUT</AllowedMethod>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

这是用于发送请求的 javascript 示例。我意识到它在移动设备上似乎根本不发送。状态码显示为 0。

function getSignedRequest(file){
  var xhr = new XMLHttpRequest();
  xhr.open("GET", "/sign_s3?file_name="+file.name+"&file_type="+file.type);
  xhr.onreadystatechange = function(){
    if(xhr.readyState === 4){
      if(xhr.status === 200){
        var response = JSON.parse(xhr.responseText);
        uploadFile(file, response.data, response.url);
      }
      else{
        alert("Could not get signed URL.");
      }
    }
  };
  xhr.send();
}

uploadFile只是一个单独的函数,最终发布图像。

我不知道是什么导致了这种差异。我怎样才能得到这个工作?

标签: javascriptpythondjangoamazon-web-servicesamazon-s3

解决方案


代替:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedMethod>PUT</AllowedMethod>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

尝试以这种方式添加 CORSRules:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
...
</CORSConfiguration>

推荐阅读