s3 的跨源请求被阻止

发布于 01-12 21:58 字数 5983 浏览 5 评论 0原文

我有预先分配的 URL 和策略(在 django 上创建),以便将对象直接从 JavaScript 上传到 S3。它在开发期间和本地服务器中按预期工作。当我在线上传到主机和服务器时,它会给我在 Firefox 和 Chrome 上阻止跨源请求的错误,它说请求已被中止。我也允许所有域进入存储桶。我什至已经把这个桶公开了。以下是我的存储桶策略和 cors 策略。我会很高兴找到解决方案。

桶策略

{
"Version": "2012-10-17",
"Statement": [
    {
        "Sid": "Stmt1621532678577",
        "Effect": "Allow",
        "Principal": "*",
        "Action": [
            "s3:PutObject",
            "s3:GetObjectAcl",
            "s3:GetObject",
            "s3:ListBucket",
            "s3:DeleteObject",
            "s3:PutObjectAcl"
        ],
        "Resource": [
            "arn:aws:s3:::[bucketname]/*",
            "arn:aws:s3:::[bucket-name]"
        ]
    }

跨域资源共享(CORS)

[
{
    "AllowedHeaders": [
        "*"
    ],
    "AllowedMethods": [
        "PUT",
        "HEAD",
        "POST",
        "DELETE"
    ],
    "AllowedOrigins": [
        "*"
    ],
    "ExposeHeaders": [
        "x-amz-server-side-encryption",
        "x-amz-request-id",
        "x-amz-id-2"
    ]
}

JavaScript函数

 // auto-upload on file input change.
$(document).on('change','.cfeproj-upload-file', function(event){
    var selectedFiles = $(this).prop('files');
    formItem = $(this).parent()
    $.each(selectedFiles, function(index, item){
        var myFile = verifyFileIsImageMovieAudio(item)
        if (myFile){
          uploadFile(myFile)
        } else {
          alert("invalid file chosen.")
        }
    })
    $(this).val('');

})


function constructFormPolicyData(policyData, fileItem) {
   var contentType = fileItem.type != '' ? fileItem.type : 'application/octet-stream'
    var url = policyData.url
    var filename = policyData.filename
    var repsonseUser = policyData.user
    // var keyPath = 'www/' + repsonseUser + '/' + filename
    var keyPath = policyData.file_bucket_path
    var fd = new FormData()
    fd.append('key', keyPath + filename);
    fd.append('acl','private');
    fd.append('Content-Type', contentType);
    fd.append("AWSAccessKeyId", policyData.key)
    fd.append('Policy', policyData.policy);
    fd.append('filename', filename);
    fd.append('Signature', policyData.signature);
    fd.append('file', fileItem);
    return fd
}

function fileUploadComplete(js_profile){
    // get the new video url 
    // put the url on the vidoe tag
    // put a completed tag as
    $.ajax({
        method:"POST",
        data: {js_profile:js_profile },
        url: "{% url 'start:upload_complete' %}",
        success: function(data){
          var vid_div = document.getElementsByClassName('js_profile_video')
          for(var i = 0; i < vid_div.length; i++){
            var nvid = document.createElement('video')
            nvid.controls = true
            nvid.muted = true
            nvid.setAttribute('width', '100%')
            // nvid.style.borderRadius = '10px'
            vid_div[i].innerHTML = ''
            vid_div[i].appendChild(nvid)
            addSourceToVideo(nvid, data, 'video/mp4');
            nvid.play();
          }
          var completed = $('#percentage_row')
          completed.html("")
          var htm = `<div class="center"><p class="green-text">your video is uploaded successfuly</p></div>`
          completed.append(htm)
        },
        error: function(jqXHR, textStatus, errorThrown){ 
            alert("An error occured, please refresh the page.")
        }
    })
}

function displayItems(fileItemList){
    var itemList = $('#percentage_row')
    itemList.html("")
    $.each(fileItemList, function(index, obj){
        var item = obj.file
        var id_ = obj.id
        var order_ = obj.order
        var html_ = "<div class=\"progress\">" + 
          "<div class=\"determinate\" style='width:" + item.progress + "%'></div></div>"
        itemList.append(html_)
    })
}

function uploadFile(fileItem){
    var policyData;
    var newLoadingItem;
    // get AWS upload policy for each file uploaded through the POST method
    // Remember we're creating an instance in the backend so using POST is
    // needed.
    js_profile = $('#js_job_profile').val()
    $.ajax({
        method:"POST",
        data: { filename: fileItem.name, js_profile: js_profile },
        url: "{% url 'start:upload_policy' %}",
        success: function(data){ policyData = data },
        error: function(data){
            alert("An error occured, please try again later"+ data)
        }
    }).done(function(){
        // construct the needed data using the policy for AWS
        var fd = constructFormPolicyData(policyData, fileItem)
        // use XML http Request to Send to AWS. 
        var xhr = new XMLHttpRequest()
        // construct callback for when uploading starts
        xhr.upload.onloadstart = function(event){
            var inLoadingIndex = $.inArray(fileItem, fileItemList)
            if (inLoadingIndex == -1){
                // Item is not loading, add to inProgress queue
                newLoadingItem = {
                    file: fileItem,
                    id: policyData.file_id,
                    order: fileItemList.length + 1
                }
                fileItemList.push(newLoadingItem)
                }
            fileItem.xhr = xhr
        }
        // Monitor upload progress and attach to fileItem.
        xhr.upload.addEventListener("progress", function(event){
            if (event.lengthComputable) {
                var progress = Math.round(event.loaded / event.total * 100);
                fileItem.progress = progress
                displayItems(fileItemList)
            }
        })

        xhr.upload.addEventListener("load", function(event){
            console.log("Complete")
            fileUploadComplete(js_profile)
        })
        xhr.open('POST', policyData.url, true );
        xhr.send(fd);
    })
}});
// end of video upload module

I have my pre-assigned URL and policy (created on django) for object to be uploaded into S3 directly from JavaScript. It works as expected during development and in local server. as soon as I upload to host and server online it give me the error of cross origin request blocked on Firefox and on chrome, it says that the request has been aborted. I have allowed all the domains to on bucket as well. I have even put the bucket public. below is my bucket policy and cors policy. I would be so happy for find a solution for this.

Bucket Policy

{
"Version": "2012-10-17",
"Statement": [
    {
        "Sid": "Stmt1621532678577",
        "Effect": "Allow",
        "Principal": "*",
        "Action": [
            "s3:PutObject",
            "s3:GetObjectAcl",
            "s3:GetObject",
            "s3:ListBucket",
            "s3:DeleteObject",
            "s3:PutObjectAcl"
        ],
        "Resource": [
            "arn:aws:s3:::[bucketname]/*",
            "arn:aws:s3:::[bucket-name]"
        ]
    }

Cross-origin resource sharing (CORS)

[
{
    "AllowedHeaders": [
        "*"
    ],
    "AllowedMethods": [
        "PUT",
        "HEAD",
        "POST",
        "DELETE"
    ],
    "AllowedOrigins": [
        "*"
    ],
    "ExposeHeaders": [
        "x-amz-server-side-encryption",
        "x-amz-request-id",
        "x-amz-id-2"
    ]
}

JavaScript function

 // auto-upload on file input change.
$(document).on('change','.cfeproj-upload-file', function(event){
    var selectedFiles = $(this).prop('files');
    formItem = $(this).parent()
    $.each(selectedFiles, function(index, item){
        var myFile = verifyFileIsImageMovieAudio(item)
        if (myFile){
          uploadFile(myFile)
        } else {
          alert("invalid file chosen.")
        }
    })
    $(this).val('');

})


function constructFormPolicyData(policyData, fileItem) {
   var contentType = fileItem.type != '' ? fileItem.type : 'application/octet-stream'
    var url = policyData.url
    var filename = policyData.filename
    var repsonseUser = policyData.user
    // var keyPath = 'www/' + repsonseUser + '/' + filename
    var keyPath = policyData.file_bucket_path
    var fd = new FormData()
    fd.append('key', keyPath + filename);
    fd.append('acl','private');
    fd.append('Content-Type', contentType);
    fd.append("AWSAccessKeyId", policyData.key)
    fd.append('Policy', policyData.policy);
    fd.append('filename', filename);
    fd.append('Signature', policyData.signature);
    fd.append('file', fileItem);
    return fd
}

function fileUploadComplete(js_profile){
    // get the new video url 
    // put the url on the vidoe tag
    // put a completed tag as
    $.ajax({
        method:"POST",
        data: {js_profile:js_profile },
        url: "{% url 'start:upload_complete' %}",
        success: function(data){
          var vid_div = document.getElementsByClassName('js_profile_video')
          for(var i = 0; i < vid_div.length; i++){
            var nvid = document.createElement('video')
            nvid.controls = true
            nvid.muted = true
            nvid.setAttribute('width', '100%')
            // nvid.style.borderRadius = '10px'
            vid_div[i].innerHTML = ''
            vid_div[i].appendChild(nvid)
            addSourceToVideo(nvid, data, 'video/mp4');
            nvid.play();
          }
          var completed = $('#percentage_row')
          completed.html("")
          var htm = `<div class="center"><p class="green-text">your video is uploaded successfuly</p></div>`
          completed.append(htm)
        },
        error: function(jqXHR, textStatus, errorThrown){ 
            alert("An error occured, please refresh the page.")
        }
    })
}

function displayItems(fileItemList){
    var itemList = $('#percentage_row')
    itemList.html("")
    $.each(fileItemList, function(index, obj){
        var item = obj.file
        var id_ = obj.id
        var order_ = obj.order
        var html_ = "<div class=\"progress\">" + 
          "<div class=\"determinate\" style='width:" + item.progress + "%'></div></div>"
        itemList.append(html_)
    })
}

function uploadFile(fileItem){
    var policyData;
    var newLoadingItem;
    // get AWS upload policy for each file uploaded through the POST method
    // Remember we're creating an instance in the backend so using POST is
    // needed.
    js_profile = $('#js_job_profile').val()
    $.ajax({
        method:"POST",
        data: { filename: fileItem.name, js_profile: js_profile },
        url: "{% url 'start:upload_policy' %}",
        success: function(data){ policyData = data },
        error: function(data){
            alert("An error occured, please try again later"+ data)
        }
    }).done(function(){
        // construct the needed data using the policy for AWS
        var fd = constructFormPolicyData(policyData, fileItem)
        // use XML http Request to Send to AWS. 
        var xhr = new XMLHttpRequest()
        // construct callback for when uploading starts
        xhr.upload.onloadstart = function(event){
            var inLoadingIndex = $.inArray(fileItem, fileItemList)
            if (inLoadingIndex == -1){
                // Item is not loading, add to inProgress queue
                newLoadingItem = {
                    file: fileItem,
                    id: policyData.file_id,
                    order: fileItemList.length + 1
                }
                fileItemList.push(newLoadingItem)
                }
            fileItem.xhr = xhr
        }
        // Monitor upload progress and attach to fileItem.
        xhr.upload.addEventListener("progress", function(event){
            if (event.lengthComputable) {
                var progress = Math.round(event.loaded / event.total * 100);
                fileItem.progress = progress
                displayItems(fileItemList)
            }
        })

        xhr.upload.addEventListener("load", function(event){
            console.log("Complete")
            fileUploadComplete(js_profile)
        })
        xhr.open('POST', policyData.url, true );
        xhr.send(fd);
    })
}});
// end of video upload module

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文