javascript - mostrar - Carga de archivos de Blueimp: varias cargas directamente a S3
javascript load image from file (1)
Autor de JQuery File Upload aquí.
La razón por la que los archivos no se envían individualmente es la opción forceIframeTransport
, que se establece en true
en su ejemplo.
La documentación de la opción singleFileUploads indica lo siguiente:
De forma predeterminada, cada archivo de una selección se carga utilizando una solicitud individual para cargas de tipo XHR .
Si bien la documentación de la opción forceIframeTransport establece lo siguiente:
Establezca esta opción en verdadero para forzar las cargas de transporte de iframe, incluso si el navegador puede subir archivos XHR .
Por lo tanto, la solución es habilitar CORS en el depósito S3 y no habilitar la opción forceIframeTransport
.
Por cierto, la mayoría de los ejemplos de integración son contribuciones de los usuarios (incluidas las guías de carga S3). Aquí hay otro que usa la característica S3 CORS y puede ayudar a su salida (aunque no lo he probado): http://pjambet.github.io/blog/direct-upload-to-s3/
Después de buscar en los últimos días, he encontrado a casi 30 personas diferentes que hacen esta misma pregunta, y no he encontrado una respuesta. Una pareja informó que encontraron una solución, pero no la proporcionaron, así que espero que alguien la pueda responder aquí.
Usando blueimp jQuery File Upload , ¿cómo puedes subir múltiples archivos directamente a Amazon S3?
Problema : S3 acepta solo un archivo por solicitud .
Solución : use blueimp jQuery File Upload para enviar solicitudes por separado para cada archivo.
Barricada : No puedo encontrar la manera de hacer que BlueJuit File Upload JQuery haga esto.
Intento de solución
La guía está aquí: https://github.com/blueimp/jQuery-File-Upload/wiki/Upload-directly-to-S3
S3 actualmente requiere más campos de formulario que los que se muestran en la guía. Aquí hay una versión recortada de mi código:
$('':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
Cuando intento subir un solo archivo, ¡funciona genial! Pero cuando intento cargar varios archivos, S3 devuelve el error 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>
Análisis
La documentación de Bluebum jQuery File Upload dice esto (debajo de add
):
Si la opción singleFileUploads está habilitada (que es la predeterminada), se llamará una vez a la devolución de llamada para cada archivo en la selección de archivos XHR cargados, con una longitud de matriz de archivos data.files, ya que cada archivo se carga individualmente.
Aquí es donde estoy atrapado:
Si "each file is uploaded individually"
a S3, ¿por qué S3 dice lo contrario?
Además, independientemente de la cantidad de archivos, la función de add
solo se ejecuta una vez. (Yo verifico esto con la declaración console.log
.) Veo 2 posibles razones para esto:
- El complemento detiene presentaciones posteriores después de que uno falla.
- El complemento no está enviando archivos de forma individual (por el motivo que sea).
¿Es incorrecto mi código? ¿Me falta una opción en el complemento o el complemento no es compatible con varias subidas directas a S3?
Actualizar
Aquí hay un archivo html para realizar pruebas rápidas: http://pastebin.com/mUBgr4MP