После поиска последних двух дней, я нашел около 30 разных людей, задающих этот же вопрос, и я не нашел ответа. Пара сообщила, что они нашли решение, но не предоставили его, поэтому я надеюсь, что кто-то сможет ответить на него здесь.
Использование Загрузка файла blueimp jQuery, как вы можете загружать несколько файлов напрямую к Amazon S3?
Проблема: S3 принимает только один файл за запрос.
Решение: используйте blueimp jQuery Загрузка файлов для отправки отдельных запросов для каждого файла.
Roadblock: я не могу понять, как сделать 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 говорит об этом (под add
):
Если опция singleFileUploads включена (которая по умолчанию), вызов обратного вызова будет вызываться один раз для каждого файла в выборе для загрузки файлов XHR с длиной массива data.files, поскольку каждый файл загружается индивидуально.
Вот где я застрял:
Если "each file is uploaded individually"
- S3, почему S3 говорит иначе?
Кроме того, независимо от количества файлов функция add
запускается только один раз. (Я проверяю это с помощью инструкции console.log
.) Я вижу 2 возможных причины для этого:
- Плагин останавливает дальнейшие представления после того, как один из них завершился неудачей.
- Плагин не отправляет файлы по отдельности (по какой-либо причине).
Неправильно ли мой код, не хватает ли опции в плагине, или плагин не поддерживает несколько прямых загрузок на S3?
Update
Здесь html файл для быстрого тестирования: http://pastebin.com/mUBgr4MP