How do I client-side upload a viewable file to Amazon S3?

前端 未结 7 1358
别那么骄傲
别那么骄傲 2020-12-13 15:20

Let me start of by saying that I am normally very reluctant to post this questions as I always feel that there\'s an answer to everything SOMEWHERE on the internet. After sp

7条回答
  •  粉色の甜心
    2020-12-13 16:07

    step 1: Set s3 policy:

    {
        "expiration": "2040-01-01T00:00:00Z",
        "conditions": [
                        {"bucket": "S3_BUCKET_NAME"},
                        ["starts-with","$key",""],
                        {"acl": "public-read"},
                        ["starts-with","$Content-Type",""],
                        ["content-length-range",0,524288000]
                      ]
    }
    

    step 2: prepare aws keys,policy,signature, in this example, all stored at s3_tokens dictionary

    the trick here is in the policy & signature policy: 1) save step 1 policy in a file. dump it to a json file. 2) base 64 encoded json file (s3_policy_json):

    #python
    policy = base64.b64encode(s3_policy_json)
    

    signature:

    #python
    s3_tokens_dict['signature'] = base64.b64encode(hmac.new(AWS_SECRET_ACCESS_KEY, policy, hashlib.sha1).digest())
    

    step 3: from your js

    $scope.upload_file = function(file_to_upload,is_video) {
        var file = file_to_upload;
        var key = $scope.get_file_key(file.name,is_video);
        var filepath = null;
        if ($scope.s3_tokens['use_s3'] == 1){
           var fd = new FormData();
           fd.append('key', key);
           fd.append('acl', 'public-read'); 
           fd.append('Content-Type', file.type);      
           fd.append('AWSAccessKeyId', $scope.s3_tokens['aws_key_id']);
           fd.append('policy', $scope.s3_tokens['policy']);
           fd.append('signature',$scope.s3_tokens['signature']);
           fd.append("file",file);
           var xhr = new XMLHttpRequest();
           var target_url = 'http://s3.amazonaws.com//';
           target_url = target_url.replace('',$scope.s3_tokens['bucket_name']);
           xhr.open('POST', target_url, false); //MUST BE LAST LINE BEFORE YOU SEND 
           var res = xhr.send(fd);
           filepath = target_url.concat(key);
        }
        return filepath;
    };
    

提交回复
热议问题