经过几天的搜索,我发现近30个不同的人都问了这个问题,但我没有找到答案。有几个人报告说他们找到了解决方案,但没有提供,所以我希望有人能在这里回答。
如何使用blueimp jQuery文件上传将多个文件直接上传到Amazon S3?
问题:S3仅接受每个请求一个文件。
解决方案:使用blueimp jQuery文件上传为每个文件发送单独的请求。
障碍:我无法弄清楚如何让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);
}
});
});
错误
当我尝试上传单个文件时,一切都很顺利!但是当我尝试上传多个文件时,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
下说:
如果启用单个文件上传选项(默认情况下),则对于XHR文件上传,将为选择的每个文件调用一次添加回调,其中
data.files
数组长度为1,因为每个文件都是单独上传的。
这就是我卡住的地方:
如果S3将"每个文件都是单独上传"
,为什么S3说不是?
而且,无论文件数量多少,add
函数只运行一次。(我用console.log
语句验证了这一点。)我看到两个可能的原因:
- 插件在一个失败后停止进一步提交。
- 插件没有单独提交文件(出于任何原因)。
我的代码是否有误,我是否在插件中漏掉了某个选项,或者插件是否不支持多个直接上传到S3?
更新
这里有一个用于快速测试的HTML文件: http://pastebin.com/mUBgr4MP