简体   繁体   中英

Set random file name when upload file to AWS S3 with pre-signed POST url

I use signed POST url with jQuery-file-upload to upload image to AWS S3 directly.

It work fine on my PC, but when I test with iPhone, I fine out that iOS will upload any picture with same name like image.png or image.jpeg .

That make the image upload finished last replace any image upload successed before it.

I generate presigned post with boto3 in Python3 like this:

post = s3.generate_presigned_post(
    Bucket='?????????',
    Key=get_random_string(8,'simple') + '/${filename}',
    Fields={
        'success_action_status': '201',
        'acl': 'public-read'
    },
    Conditions=[{
            'success_action_status': '201'
        },
        {
            'acl': 'public-read'
        },
        ["starts-with", "$Content-Type", ""]
    ]
)
post['fields'] = json.dumps(post['fields'])

And here is my javascript code:

$(function () {
    'use strict';

    var form = $('#fileupload');
    // Initialize the jQuery File Upload widget:
    $('#fileupload').fileupload({
        dropZone: $('#dropzone'),
        previewMaxHeight: 300,
        previewMaxWidth: 300,
        acceptFileTypes:  /(\.|\/)(gif|jpe?g|png)$/i,
        dataType: 'XML',
        getFilesFromResponse: function (data) {
            var key = $(data.jqXHR.responseXML).find("Key").text();
            var url = $(data.jqXHR.responseXML).find("Location").text();
            return [{
                url: url,
                name: key,
                thumbnailUrl: url,
            }];
        },
    }).on('fileuploadsubmit', function (e, data) {
        data.formData = (function (form) {
            var r = form.serializeArray();
            $.each(form.data('theform-data'), function(k, v) {
                r.push({name: k , value: v})
            });
            return r;
        })(data.form);
        data.formData.push({name: "Content-Type" , value: data.files[0].type});
    });
});

The get_random_string(8,'simple') in Python just can prevent same file name in different upload, but it cannot prevent same file name when user upload multifile at the same time (because they upload with same pre-signed POST url).

So I wonder if there has any way that I can set random file name when upload file to AWS S3 with pre-signed POST url?

I found out that this would work:

$(function () {
    'use strict';

    var form = $('#fileupload');
    // Initialize the jQuery File Upload widget:
    $('#fileupload').fileupload({
        dropZone: $('#dropzone'),
        previewMaxHeight: 300,
        previewMaxWidth: 300,
        acceptFileTypes:  /(\.|\/)(gif|jpe?g|png)$/i,
        dataType: 'XML',
        getFilesFromResponse: function (data) {
            var key = $(data.jqXHR.responseXML).find("Key").text();
            var url = $(data.jqXHR.responseXML).find("Location").text();
            return [{
                url: url,
                name: key,
                thumbnailUrl: url,
            }];
        },
    }).on('fileuploadsubmit', function (e, data) {
        data.formData = (function (form) {
            var r = form.serializeArray();
            $.each(form.data('theform-data'), function(k, v) {
                if (k == "key") {
                    var filename = v.split("/");
                    var random_prefix = filename[0];
                    var ext = data.files[0].name.split(".").slice(-1)[0];
                    v = random_prefix + '/'
                        + (function (length, chars) {
                            var result = '';
                            for (var i = length; i > 0; --i) result += chars[Math.floor(Math.random() * chars.length)];
                            return result;
                        })(10, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
                        + '.' + ext.toLowerCase();
                };
                r.push({name: k , value: v})
            });
            return r;
        })(data.form);
        data.formData.push({name: "Content-Type" , value: data.files[0].type});
    });
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM