在搜索过去的几天之后,我发现有近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
答案 0 :(得分:8)
JQuery File Upload的作者。
单独提交文件的原因是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