After searching the past couple days, I've found nearly 30 different people asking this same question, and I haven't found an answer. A couple reported that they found a solution, but did not provide it, so I'm hoping someone could answer it here.
Using blueimp jQuery File Upload, how can you upload multiple files directly to Amazon S3?
Problem: S3 accepts only one file per request.
Solution: Use blueimp jQuery File Upload to send separate requests for each file.
Roadblock: I cannot figure out how to make blueimp jQuery File Upload do this.
Solution Attempt
The guide is here: https://github.com/blueimp/jQuery-File-Upload/wiki/Upload-directly-to-S3
S3 currently requires more form fields than the ones shown in the guide. Here's a trimmed down version of my code:
$(':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);
}
});
});
Error
When I try to upload a single file, it works great! But when I try to upload multiple files, S3 returns this 400
error:
<?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>
Analysis
The blueimp jQuery File Upload documentation says this (under 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.
This is where I'm stuck:
If "each file is uploaded individually"
to S3, why does S3 say otherwise?
Also, regardless of the number of files, the add
function runs only once. (I verify this with the console.log
statement.) I see 2 likely reasons for this:
- The plugin stops further submissions after one fails.
- The plugin is not submitting files individually (for whatever reason).
Is my code incorrect, am I missing an option in the plugin, or does the plugin not support multiple direct uploads to S3?
Update
Here's an html file for quick testing: http://pastebin.com/mUBgr4MP
data.submit(); //why is this submitting all files at once?
inside the success callback – Sealydata
object beforedata.submit();
. Does it has only one file infiles
array? – Nicknack