Blueimp文件上传 - 多个直接上传到S3

Gre*_*n23 13 javascript jquery file-upload amazon-s3 blueimp

经过几天的搜索,我发现近30个不同的人都在问同样的问题,但我还没有找到答案.一对夫妇报告说他们找到了解决办法,但没有提供,所以我希望有人能在这里回答.


使用blueimp jQuery文件上传,如何将多个文件直接上传到Amazon S3?

问题:S3 每个请求只接受一个文件.

解决方案:使用blueimp jQuery File Upload为每个文件发送单独的请求.

包版:我无法弄清楚如何使blueimp jQuery文件上传这样做.


解决方案尝试

该指南在这里:https://github.com/blueimp/jQuery-File-Upload/wiki/Upload-directly-to-S3

S3目前需要的表单字段多于指南中显示的字段.这是我的代码的精简版:

$(':file').each(function(i, el) {

    var fileInput = $(el);
    var form = fileInput.parents('form:first');

    fileInput.fileupload({
        forceIframeTransport: true,
        autoUpload: true,
        singleFileUploads: true, //default anyway
        add: function(event, data) {
            var files = data.files || [];
            var nextInQueue = files[0]; //this is a queue, not a list
            console.log('nextInQueue:', nextInQueue);
            if (!nextInQueue) return;

            var fileData = {name: nextInQueue.name, mime: nextInQueue.type, size: nextInQueue.size};

            $.ajax({
                url: '/s3stuff',
                type: 'POST',
                dataType: 'json',
                data: {'file': fileData},
                async: false,
                success: function(res) {
                    form.find('input[name="key"]').val(res.key);
                    form.find('input[name="AWSAccessKeyId"]').val(res.AWSAccessKeyId);
                    form.find('input[name="policy"]').val(res.policy);
                    form.find('input[name="signature"]').val(res.signature);
                    form.find('input[name="acl"]').val(res.acl);
                    form.find('input[name="success_action_status"]').val(res.success_action_status);
                    form.find('input[name="Content-Type"]').val(nextInQueue.type);
                    form.attr('action', res.url);

                    data.submit(); //why is this submitting all files at once?
                }
            });
        },
        fail: function(err) {
            console.log('err:', err.stack);
        }
    });
});
Run Code Online (Sandbox Code Playgroud)

错误

当我尝试上传单个文件时,效果很好!但是当我尝试上传多个文件时,S3会返回以下400错误:

<?xml version="1.0" encoding="UTF-8"?>
<Error>
    <Code>InvalidArgument</Code>
    <Message>POST requires exactly one file upload per request.</Message>
    <ArgumentName>file</ArgumentName>
    <ArgumentValue>2</ArgumentValue>
</Error>
Run Code Online (Sandbox Code Playgroud)

分析

blueimp jQuery的文件上传的文件说,这(下add):

如果启用了singleFileUploads选项(这是默认设置),则对于XHR文件上载选择中的每个文件,将调用一次add回调,data.files数组长度为1,因为每个文件都是单独上载的.

这就是我被困的地方:
如果"each file is uploaded individually"是S3,为什么S3会这样说呢?

此外,无论文件数量多少,该add函数只运行一次.(我在console.log声明中对此进行了验证.)我看到了两个可能的原因:

  1. 插件失败后,插件会停止进一步提交.
  2. 该插件不是单独提交文件(无论出于何种原因).

我的代码是不正确的,我是否错过了插件中的选项,或插件是否支持多次直接上传到S3?


更新

这是一个用于快速测试的html文件:http: //pastebin.com/mUBgr4MP

小智 9

这里是JQuery文件上传的作者.

文件未单独提交的原因是forceIframeTransport选项,true在您的示例中设置.

singleFileUploads选项文档说明如下:

默认情况下,使用针对XHR类型上载的单独请求上载选择的每个文件.

虽然forceIframeTransport选项文档说明如下:

将此选项设置为true以强制iframe传输上载,即使浏览器能够上载XHR文件也是如此.

因此,解决方案是在S3存储桶上启用CORS并且启用该true选项.

顺便说一下,大多数集成示例都是用户贡献(包括S3上载指南).这是另一个使用S3 CORS功能并可能帮助你的人(虽然没有测试过):http: //pjambet.github.io/blog/direct-upload-to-s3/

  • 好消息@ GreenRaccoon23 - 很高兴听到长期运行的问题现在有了解决方案.我已将奖金授予Seb. (2认同)