2017-09-23 24 views
0

私は過去数時間この問題を解決しようとしています。S3 Ajax CORSエラー

私はhereの輪郭を描いたHeroku S3 pythonアプリの直接アップロード方法を使用しています。

基本的に、私は私が

getSignedRequestで
$('#files').on('change', function() { 
    var files = document.getElementById("files").files; 
    var file = files[0]; 
    if(!file){ 
     return alert("No file selected."); 
    } 
    getSignedRequest(file); 
}) 

でからファイルを取得するファイルの入力を持って、私は次のように私のsign_s3ルート

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(); 
     } 

への要求がsign_s3ルートが定義されていることを確認

@main.route('/sign_s3/') 
def sign_s3(): 
    S3_BUCKET = os.environ.get('S3_BUCKET') 

    file_name = request.args.get('file_name') 
    file_type = request.args.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 json.dumps({ 
    'data': presigned_post, 
    'url': 'https://%s.s3.amazonaws.com/%s' % (S3_BUCKET, file_name) 
    }) 

uploadFile関数はd

function uploadFile(file, s3Data, url){ 
      var xhr = new XMLHttpRequest(); 
      xhr.open("POST", s3Data.url); 

      var postData = new FormData(); 
      for(key in s3Data.fields){ 
      postData.append(key, s3Data.fields[key]); 
      } 
      postData.append('file', file); 
      console.log(file); 

      xhr.onreadystatechange = function() { 
      if(xhr.readyState === 4){ 
       if(xhr.status === 200 || xhr.status === 204){ 
       document.getElementById("preview").src = url; 
       document.getElementById("avatar-url").value = url; 
       } 
       else{ 
       alert("Could not upload file."); 
       } 
      } 
      }; 
      xhr.send(postData); 
     } 
     }); 

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

を次のように私のバケットCORSの設定があるしかし、私はファイルアップロード

Failed to load https://mhealth-beta-1.s3.amazonaws.com/: Redirect from 'https://mhealth-beta-1.s3.amazonaws.com/' to 'https://mhealth-beta-1.s3-us-west-2.amazonaws.com/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:5000' is therefore not allowed access. 

答えて

0

時に、次のエラーを取得中にエラーがリダイレクトを言及している。維持を次のようにefined私は302リダイレクトがCORSとどのように対話するかに精通していませんが、これを試してみてください:

バックエンドルートでは、を含むDNS名を使用してください。

ので'https://%s.s3.%s.amazonaws.com/%s' % (S3_BUCKET, region, file_name)良いキャッチがある

+0

- リダイレクトが実際に予想外であり、これは、少なくとも潜在的な問題を解消するが、S3 'ことに注意してください - $ {地域}のために有効ではありません.amazonaws.com'すべての地域。古い地域だけがそのフォーマットを使用していました。新しい領域は 's3'の後にダッシュではなくドットを使い、us-east-1は' s3-external-1'を使います。現時点で有効な唯一の一貫したパターンは 'bucket.s3.dualstack。$ {region} .amazonaws.com'です。私はいつも 'localhost'がCORSテストの正当な起源ではないという仮定から作業しました。なぜなら、それは実際のドメインではないからです。 –

+0

私はドットの表記がどこでもサポートされているとは確信していますが、これは明示的に文書化されていません。いずれにせよ、これはOPの問題ではありません。 – prestomation

+0

はい、ドット記法をサポートするために古いSSL証明書を古い地域に展開していたようですが、歴史的にはそうではなく、[地域とエンドポイント](http:// docs.aws.amazon.com/general/latest/gr/rande.html#s3_region)。同意します、しかし...それは問題ではありません、ここで。 –

関連する問題