Parece que no he comunicado claramente mi problema. Necesito enviar un archivo (usando AJAX) y necesito obtener el progreso de carga del archivo usando Nginx HttpUploadProgressModule . Necesito una buena solución a este problema. Lo intenté con el complemento jquery.uploadprogress, pero me veo obligado a reescribir gran parte del mismo para que funcione en todos los navegadores y para enviar el archivo mediante AJAX.
Todo lo que necesito es el código para hacer esto y debe funcionar en todos los principales navegadores (Chrome, Safari, FireFox e IE). Sería aún mejor si pudiera obtener una solución que maneje múltiples cargas de archivos.
Estoy usando el complemento jquery.uploadprogress para obtener el progreso de carga de un archivo desde NginxHttpUploadProgressModule. Esto está dentro de un iframe para una aplicación de Facebook. Funciona en firefox, pero falla en chrome/safari.
Cuando abro la consola me sale esto.
Uncaught ReferenceError: progressFrame is not defined jquery.uploadprogress.js:80¿Alguna idea de cómo arreglaría eso?
También me gustaría enviar el archivo usando AJAX cuando esté completo. ¿Cómo implementaría eso?
EDITAR:
Necesito esto pronto y es importante, así que voy a ofrecer una recompensa de 100 puntos por esta pregunta. La primera persona que responda recibirá los 100 puntos.
EDITAR 2:
Jake33 me ayudó a resolver el primer problema. La primera persona que deje una respuesta sobre cómo enviar el archivo con ajax también recibirá los 100 puntos.
Cargar archivos es realmente posible con AJAX en estos días. Sí, AJAX, no algunos aspirantes a AJAX de mierda como swf o java.
Este ejemplo podría ayudarte: https://webblocks.nl/tests/ajax/file-drag-drop.html
(También incluye la interfaz de arrastrar y soltar, pero eso se ignora fácilmente).
Básicamente a lo que se reduce es a esto:
<input id="files" type="file" /> <script> document.getElementById('files').addEventListener('change', function(e) { var file = this.files[0]; var xhr = new XMLHttpRequest(); (xhr.upload || xhr).addEventListener('progress', function(e) { var done = e.position || e.loaded var total = e.totalSize || e.total; console.log('xhr progress: ' + Math.round(done/total*100) + '%'); }); xhr.addEventListener('load', function(e) { console.log('xhr upload complete', e, this.responseText); }); xhr.open('post', '/URL-HERE', true); xhr.send(file); }); </script>(demostración: http://jsfiddle.net/rudiedirkx/jzxmro8r/ )
Entonces, básicamente, todo se reduce a esto =)
xhr.send(file); Donde file es typeof Blob : http://www.w3.org/TR/FileAPI/
Otra forma (mejor IMO) es usar FormData . Esto le permite 1) nombrar un archivo, como en un formulario y 2) enviar otras cosas (también archivos), como en un formulario.
var fd = new FormData; fd.append('photo1', file); fd.append('photo2', file2); fd.append('other_data', 'foo bar'); xhr.send(fd); FormData hace que el código del servidor sea más limpio y más compatible con versiones anteriores (ya que la solicitud ahora tiene exactamente el mismo formato que los formularios normales).
No todo es experimental, pero sí muy moderno. Chrome 8+ y Firefox 4+ saben qué hacer, pero no conozco ningún otro.
Así es como manejé la solicitud (1 imagen por solicitud) en PHP:
if ( isset($_FILES['file']) ) { $filename = basename($_FILES['file']['name']); $error = true; // Only upload if on my home win dev machine if ( isset($_SERVER['WINDIR']) ) { $path = 'uploads/'.$filename; $error = !move_uploaded_file($_FILES['file']['tmp_name'], $path); } $rsp = array( 'error' => $error, // Used in JS 'filename' => $filename, 'filepath' => '/tests/uploads/' . $filename, // Web accessible ); echo json_encode($rsp); exit; }Aquí hay algunas opciones para usar AJAX para cargar archivos:
AjaxFileUpload : requiere un elemento de formulario en la página, pero carga el archivo sin recargar la página. Ver la demostración .
Uploadify : un método basado en Flash para cargar archivos.
Diez ejemplos de carga de archivos AJAX : esto se publicó este año.
ACTUALIZACIÓN: aquí hay un complemento JQuery para la carga de archivos múltiples .