Blueimp 文件上传 - 直接多次上传到 S3
Posted
技术标签:
【中文标题】Blueimp 文件上传 - 直接多次上传到 S3【英文标题】:Blueimp File Upload - Multiple Uploads Directly to S3 【发布时间】:2016-11-22 21:14:04 【问题描述】:在过去几天的搜索之后,我发现有近 30 个不同的人在问同样的问题,但我没有找到答案。一对夫妇报告说他们找到了解决方案,但没有提供,所以我希望有人能在这里回答。
使用blueimp jQuery File Upload,如何将多个文件直接上传到Amazon S3?
问题:S3每个请求只接受一个文件。
解决方案:使用blueimp jQuery File Upload 为每个文件发送单独的请求。
障碍:我不知道如何让blueimp jQuery File Upload 做到这一点。
解决方案尝试
指南在这里: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);
);
);
错误
当我尝试上传单个文件时,效果很好!但是当我尝试上传多个文件时,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>
分析
blueimp jQuery File Upload documentation 这么说(在add
下):
如果启用了 singleFileUploads 选项(这是默认设置),将为 XHR 文件上传选择中的每个文件调用一次 add 回调,data.files 数组长度为 1,因为每个文件都是单独上传的.
这就是我卡住的地方:如果 "each file is uploaded individually"
到 S3,为什么 S3 不这样说?
此外,无论文件数量如何,add
函数都只运行一次。 (我用console.log
声明验证了这一点。)我看到了两个可能的原因:
-
插件在一次失败后停止进一步的提交。
插件未单独提交文件(无论出于何种原因)。
是我的代码不正确,是我在插件中遗漏了一个选项,还是插件不支持多次直接上传到 S3?
更新
这是一个用于快速测试的 html 文件: http://pastebin.com/mUBgr4MP
【问题讨论】:
你找到这个问题的答案了吗? 不幸的是,没有。我们只需要禁用多个文件上传。 好的,不用担心,我已经开始为此提供赏金,因为我的要求必须支持多个文件上传,并且您已经准确地描述了我的问题。希望我们都能得到答案。 使用文件上传插件是要求的一部分吗? 看起来您已将data.submit(); //why is this submitting all files at once?
放入成功回调中
【参考方案1】:
这里是 JQuery 文件上传的作者。
文件未单独提交的原因是forceIframeTransport
选项,在您的示例中设置为true
。
documentation for the singleFileUploads option 声明如下:
默认情况下,选择的每个文件都是使用XHR 类型上传的单独请求上传的。
虽然documentation for the forceIframeTransport option 声明如下:
将此选项设置为
true
以强制 iframe 传输上传,即使浏览器能够上传 XHR 文件。
因此,解决方案是enable CORS on the S3 bucket 并且不启用forceIframeTransport
选项。
顺便说一句,大多数集成示例都是用户贡献的(包括 S3 上传指南)。 这是另一个使用 S3 CORS 功能的,可能会帮助你(虽然还没有测试过): http://pjambet.github.io/blog/direct-upload-to-s3
【讨论】:
感谢您及时详细地回复 Sebastian 的电子邮件。 Greenracoon23你能检查并确认解决方案吗? 有效!谢谢!具体来说,它是<AllowedOrigin>
CORSRule。顺便说一句,你的插件很棒。
好消息@GreenRaccoon23 - 很高兴听到这个长期存在的问题现在有了解决方案。我已将赏金授予 Seb。
不是还要设置limitMultiFileUploads: 1
吗?否则我仍然只看到一个帖子请求。以上是关于Blueimp 文件上传 - 直接多次上传到 S3的主要内容,如果未能解决你的问题,请参考以下文章
通过 https 上传多个文件时 blueimp jquery 文件上传挂起
上传的文件的临时名称没有进入 blueimp jQuery 文件上传