经过过去几天的搜索,我发现近 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
下):
If the singleFileUploads option is enabled (which is the default), the add callback will be called once for each file in the selection for XHR file uploads, with a data.files array length of one, as each file is uploaded individually.
这是我卡住的地方:
如果 “每个文件单独上传”
到 S3,为什么 S3 不这样说?
此外,无论文件数量有多少,add
函数只运行一次。 (我用 console.log
语句验证了这一点。)我看到了 2 个可能的原因:
- 该插件会在提交失败后停止进一步提交。
- 插件不会单独提交文件(无论出于何种原因)。
我的代码是否不正确,我是否缺少插件中的选项,或者插件是否不支持多个直接上传到 S3?
更新
这是一个用于快速测试的 html 文件: http://pastebin.com/mUBgr4MP
最佳答案
JQuery 文件上传的作者在这里。
文件未单独提交的原因是 forceIframeTransport
选项,在您的示例中该选项设置为 true
。
documentation for the singleFileUploads option陈述如下:
By default, each file of a selection is uploaded using an individual request for XHR type uploads.
虽然documentation for the forceIframeTransport option陈述如下:
Set this option to
true
to force iframe transport uploads, even if the browser is capable of XHR file uploads.
所以,解决方案是enable CORS on the S3 bucket并不启用forceIframeTransport
选项。
顺便说一下,大多数集成示例都是用户贡献的(包括 S3 上传指南)。 这是另一个使用 S3 CORS 功能并可能帮助您解决问题的方法(虽然尚未测试): http://pjambet.github.io/blog/direct-upload-to-s3
关于javascript - Blueimp 文件上传 - 多个直接上传到 S3,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38467615/