使用预先签名的POST URL将文件上载到AWS S3时设置随机文件名

时间:2016-03-26 16:27:58

标签: javascript python file amazon-s3 jquery-file-upload

我使用带有jQuery-file-upload的签名POST网址直接将图像上传到AWS S3。

它可以在我的电脑上正常工作,但是当我使用iPhone进行测试时,我知道iOS会上传任何名称相同的图片,例如image.pngimage.jpeg

这使得图片上传完成最后替换之前成功上传的任何图片。

我在Python3中使用boto3生成预先发布的帖子,如下所示:

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'])

这是我的javascript代码:

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

Python中的get_random_string(8,'simple')只能在不同的上传中阻止相同的文件名,但是当用户同时上传多文件时它不能阻止相同的文件名(因为它们使用相同的预先签名的POST URL上传)。 / p>

所以我想知道在使用预先签名的POST网址将文件上传到AWS S3时是否有任何方法可以设置随机文件名?

1 个答案:

答案 0 :(得分:0)

我发现这可行:

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